event_pipe: use g_io_channel_read_chars() to drain the pipe
For some unknown reason, read() blocks on WIN32, even though it was invoked inside the G_IO_IN callback. By switching to GIOChannel functions, this problem is solved, and it works on both Linux and Windows.
This commit is contained in:
parent
22f3ffb099
commit
8248f498b2
|
@ -38,6 +38,7 @@
|
||||||
#define G_LOG_DOMAIN "event_pipe"
|
#define G_LOG_DOMAIN "event_pipe"
|
||||||
|
|
||||||
static int event_pipe[2];
|
static int event_pipe[2];
|
||||||
|
static GIOChannel *event_channel;
|
||||||
static guint event_pipe_source_id;
|
static guint event_pipe_source_id;
|
||||||
static GMutex *event_pipe_mutex;
|
static GMutex *event_pipe_mutex;
|
||||||
static bool pipe_events[PIPE_EVENT_MAX];
|
static bool pipe_events[PIPE_EVENT_MAX];
|
||||||
|
@ -61,12 +62,15 @@ main_notify_event(G_GNUC_UNUSED GIOChannel *source,
|
||||||
G_GNUC_UNUSED gpointer data)
|
G_GNUC_UNUSED gpointer data)
|
||||||
{
|
{
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
ssize_t r = read(event_pipe[0], buffer, sizeof(buffer));
|
gsize bytes_read;
|
||||||
|
GError *error = NULL;
|
||||||
|
GIOStatus status = g_io_channel_read_chars(event_channel,
|
||||||
|
buffer, sizeof(buffer),
|
||||||
|
&bytes_read, &error);
|
||||||
|
if (status == G_IO_STATUS_ERROR)
|
||||||
|
g_error("error reading from pipe: %s", error->message);
|
||||||
|
|
||||||
bool events[PIPE_EVENT_MAX];
|
bool events[PIPE_EVENT_MAX];
|
||||||
|
|
||||||
if (r < 0 && errno != EAGAIN && errno != EINTR)
|
|
||||||
g_error("error reading from pipe: %s", strerror(errno));
|
|
||||||
|
|
||||||
g_mutex_lock(event_pipe_mutex);
|
g_mutex_lock(event_pipe_mutex);
|
||||||
memcpy(events, pipe_events, sizeof(events));
|
memcpy(events, pipe_events, sizeof(events));
|
||||||
memset(pipe_events, 0, sizeof(pipe_events));
|
memset(pipe_events, 0, sizeof(pipe_events));
|
||||||
|
@ -94,10 +98,13 @@ void event_pipe_init(void)
|
||||||
#else
|
#else
|
||||||
channel = g_io_channel_win32_new_fd(event_pipe[0]);
|
channel = g_io_channel_win32_new_fd(event_pipe[0]);
|
||||||
#endif
|
#endif
|
||||||
|
g_io_channel_set_encoding(channel, NULL, NULL);
|
||||||
|
g_io_channel_set_buffered(channel, false);
|
||||||
|
|
||||||
event_pipe_source_id = g_io_add_watch(channel, G_IO_IN,
|
event_pipe_source_id = g_io_add_watch(channel, G_IO_IN,
|
||||||
main_notify_event, NULL);
|
main_notify_event, NULL);
|
||||||
g_io_channel_unref(channel);
|
|
||||||
|
event_channel = channel;
|
||||||
|
|
||||||
event_pipe_mutex = g_mutex_new();
|
event_pipe_mutex = g_mutex_new();
|
||||||
}
|
}
|
||||||
|
@ -107,6 +114,7 @@ void event_pipe_deinit(void)
|
||||||
g_mutex_free(event_pipe_mutex);
|
g_mutex_free(event_pipe_mutex);
|
||||||
|
|
||||||
g_source_remove(event_pipe_source_id);
|
g_source_remove(event_pipe_source_id);
|
||||||
|
g_io_channel_unref(event_channel);
|
||||||
|
|
||||||
close(event_pipe[0]);
|
close(event_pipe[0]);
|
||||||
close(event_pipe[1]);
|
close(event_pipe[1]);
|
||||||
|
|
Loading…
Reference in New Issue