diff options
author | Max Kellermann <max@duempel.org> | 2009-01-30 15:56:53 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-01-30 15:56:53 +0100 |
commit | 76b217f71e5e39c0ebc433338f9c08975285561a (patch) | |
tree | f13d3c09cb601c72be473f27b2d9d80714ba6678 | |
parent | c38dd9e8d84eb7e398627bf6f2f562b2b0c35012 (diff) | |
download | mpd-76b217f71e5e39c0ebc433338f9c08975285561a.tar.gz mpd-76b217f71e5e39c0ebc433338f9c08975285561a.tar.xz mpd-76b217f71e5e39c0ebc433338f9c08975285561a.zip |
client: check for G_IO_ERR and G_IO_HUP
When we do not explicitly catch G_IO_ERR and G_IO_HUP, GLib can go
into an infinite loop, because it won't deliver the socket error to
MPD.
-rw-r--r-- | src/client.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/src/client.c b/src/client.c index ceb915d58..423aafeec 100644 --- a/src/client.c +++ b/src/client.c @@ -191,7 +191,8 @@ static void client_init(struct client *client, int fd) /* we prefer to do buffering */ g_io_channel_set_buffered(client->channel, false); - client->source_id = g_io_add_watch(client->channel, G_IO_IN, + client->source_id = g_io_add_watch(client->channel, + G_IO_IN|G_IO_ERR|G_IO_HUP, client_in_event, client); client->lastTime = time(NULL); @@ -498,13 +499,12 @@ static int client_read(struct client *client) } static gboolean -client_out_event(G_GNUC_UNUSED GIOChannel *source, - G_GNUC_UNUSED GIOCondition condition, +client_out_event(G_GNUC_UNUSED GIOChannel *source, GIOCondition condition, gpointer data); static gboolean client_in_event(G_GNUC_UNUSED GIOChannel *source, - G_GNUC_UNUSED GIOCondition condition, + GIOCondition condition, gpointer data) { struct client *client = data; @@ -512,6 +512,11 @@ client_in_event(G_GNUC_UNUSED GIOChannel *source, assert(!client_is_expired(client)); + if (condition != G_IO_IN) { + client_set_expired(client); + return false; + } + client->lastTime = time(NULL); ret = client_read(client); @@ -533,7 +538,8 @@ client_in_event(G_GNUC_UNUSED GIOChannel *source, if (!g_queue_is_empty(client->deferred_send)) { /* deferred buffers exist: schedule write */ - client->source_id = g_io_add_watch(client->channel, G_IO_OUT, + client->source_id = g_io_add_watch(client->channel, + G_IO_OUT|G_IO_ERR|G_IO_HUP, client_out_event, client); return false; } @@ -543,14 +549,18 @@ client_in_event(G_GNUC_UNUSED GIOChannel *source, } static gboolean -client_out_event(G_GNUC_UNUSED GIOChannel *source, - G_GNUC_UNUSED GIOCondition condition, +client_out_event(G_GNUC_UNUSED GIOChannel *source, GIOCondition condition, gpointer data) { struct client *client = data; assert(!client_is_expired(client)); + if (condition != G_IO_OUT) { + client_set_expired(client); + return false; + } + client_write_deferred(client); if (client_is_expired(client)) { @@ -563,7 +573,8 @@ client_out_event(G_GNUC_UNUSED GIOChannel *source, if (g_queue_is_empty(client->deferred_send)) { /* done sending deferred buffers exist: schedule read */ - client->source_id = g_io_add_watch(client->channel, G_IO_IN, + client->source_id = g_io_add_watch(client->channel, + G_IO_IN|G_IO_ERR|G_IO_HUP, client_in_event, client); return false; } |