Commit 76b217f7 authored by Max Kellermann's avatar Max Kellermann

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.
parent c38dd9e8
...@@ -191,7 +191,8 @@ static void client_init(struct client *client, int fd) ...@@ -191,7 +191,8 @@ static void client_init(struct client *client, int fd)
/* we prefer to do buffering */ /* we prefer to do buffering */
g_io_channel_set_buffered(client->channel, false); 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_in_event, client);
client->lastTime = time(NULL); client->lastTime = time(NULL);
...@@ -498,13 +499,12 @@ static int client_read(struct client *client) ...@@ -498,13 +499,12 @@ static int client_read(struct client *client)
} }
static gboolean static gboolean
client_out_event(G_GNUC_UNUSED GIOChannel *source, client_out_event(G_GNUC_UNUSED GIOChannel *source, GIOCondition condition,
G_GNUC_UNUSED GIOCondition condition,
gpointer data); gpointer data);
static gboolean static gboolean
client_in_event(G_GNUC_UNUSED GIOChannel *source, client_in_event(G_GNUC_UNUSED GIOChannel *source,
G_GNUC_UNUSED GIOCondition condition, GIOCondition condition,
gpointer data) gpointer data)
{ {
struct client *client = data; struct client *client = data;
...@@ -512,6 +512,11 @@ client_in_event(G_GNUC_UNUSED GIOChannel *source, ...@@ -512,6 +512,11 @@ client_in_event(G_GNUC_UNUSED GIOChannel *source,
assert(!client_is_expired(client)); assert(!client_is_expired(client));
if (condition != G_IO_IN) {
client_set_expired(client);
return false;
}
client->lastTime = time(NULL); client->lastTime = time(NULL);
ret = client_read(client); ret = client_read(client);
...@@ -533,7 +538,8 @@ client_in_event(G_GNUC_UNUSED GIOChannel *source, ...@@ -533,7 +538,8 @@ client_in_event(G_GNUC_UNUSED GIOChannel *source,
if (!g_queue_is_empty(client->deferred_send)) { if (!g_queue_is_empty(client->deferred_send)) {
/* deferred buffers exist: schedule write */ /* 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); client_out_event, client);
return false; return false;
} }
...@@ -543,14 +549,18 @@ client_in_event(G_GNUC_UNUSED GIOChannel *source, ...@@ -543,14 +549,18 @@ client_in_event(G_GNUC_UNUSED GIOChannel *source,
} }
static gboolean static gboolean
client_out_event(G_GNUC_UNUSED GIOChannel *source, client_out_event(G_GNUC_UNUSED GIOChannel *source, GIOCondition condition,
G_GNUC_UNUSED GIOCondition condition,
gpointer data) gpointer data)
{ {
struct client *client = data; struct client *client = data;
assert(!client_is_expired(client)); assert(!client_is_expired(client));
if (condition != G_IO_OUT) {
client_set_expired(client);
return false;
}
client_write_deferred(client); client_write_deferred(client);
if (client_is_expired(client)) { if (client_is_expired(client)) {
...@@ -563,7 +573,8 @@ client_out_event(G_GNUC_UNUSED GIOChannel *source, ...@@ -563,7 +573,8 @@ client_out_event(G_GNUC_UNUSED GIOChannel *source,
if (g_queue_is_empty(client->deferred_send)) { if (g_queue_is_empty(client->deferred_send)) {
/* done sending deferred buffers exist: schedule /* done sending deferred buffers exist: schedule
read */ 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); client_in_event, client);
return false; return false;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment