diff options
author | Teijo Kinnunen <teijo.kinnunen@uros.com> | 2020-04-15 12:15:50 +0300 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2020-04-15 19:49:17 +0200 |
commit | 49c1862af5464b0567fc6fcb8e7293ea845b28b0 (patch) | |
tree | 5b88d600a89a86689bd028207c8214e03052f089 | |
parent | d13f7d4334fc418c96c9e82a5ad2bedcde46eabe (diff) | |
download | libqmi-49c1862af5464b0567fc6fcb8e7293ea845b28b0.tar.gz |
libqmi-glib,proxy: fix loss of last requests on client hangup
If a client sends requests just before the client disconnects, these
may get lost. The reason is that connection_readable_cb() may be
called with both G_IO_IN and G_IO_HUP set; in that case the hangup
is processed immediately and received requests are lost.
This commit changes behaviour so that incoming data is processed
first (if available) before disconnecting from client.
In practice, this problem caused CID leaking with ModemManager;
the last Release CID requests could get lost when ModemManager
was closing down the QMI port.
(cherry picked from commit 16383670dcb471d6a5b802a9cca1e2a24eb86de5)
-rw-r--r-- | src/libqmi-glib/qmi-proxy.c | 49 |
1 files changed, 23 insertions, 26 deletions
diff --git a/src/libqmi-glib/qmi-proxy.c b/src/libqmi-glib/qmi-proxy.c index 2a9950fb..ef096215 100644 --- a/src/libqmi-glib/qmi-proxy.c +++ b/src/libqmi-glib/qmi-proxy.c @@ -679,38 +679,35 @@ connection_readable_cb (GSocket *socket, self = client->proxy; - if (condition & G_IO_HUP || condition & G_IO_ERR) { - untrack_client (self, client); - return FALSE; - } + if (condition & G_IO_IN || condition & G_IO_PRI) { + r = g_input_stream_read (g_io_stream_get_input_stream (G_IO_STREAM (client->connection)), + buffer, + BUFFER_SIZE, + NULL, + &error); + if (r < 0) { + g_warning ("Error reading from istream: %s", error ? error->message : "unknown"); + if (error) + g_error_free (error); + untrack_client (self, client); + return FALSE; + } - if (!(condition & G_IO_IN || condition & G_IO_PRI)) - return TRUE; + if (r > 0) { + if (!G_UNLIKELY (client->buffer)) + client->buffer = g_byte_array_sized_new (r); + g_byte_array_append (client->buffer, buffer, r); - r = g_input_stream_read (g_io_stream_get_input_stream (G_IO_STREAM (client->connection)), - buffer, - BUFFER_SIZE, - NULL, - &error); - if (r < 0) { - g_warning ("Error reading from istream: %s", error ? error->message : "unknown"); - if (error) - g_error_free (error); + /* Try to parse input messages */ + parse_request (self, client); + } + } + + if (condition & G_IO_HUP || condition & G_IO_ERR) { untrack_client (self, client); return FALSE; } - if (r == 0) - return TRUE; - - /* else, r > 0 */ - if (!G_UNLIKELY (client->buffer)) - client->buffer = g_byte_array_sized_new (r); - g_byte_array_append (client->buffer, buffer, r); - - /* Try to parse input messages */ - parse_request (self, client); - return TRUE; } |