summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeijo Kinnunen <teijo.kinnunen@uros.com>2020-04-15 12:15:50 +0300
committerAleksander Morgado <aleksander@aleksander.es>2020-04-15 19:49:17 +0200
commit49c1862af5464b0567fc6fcb8e7293ea845b28b0 (patch)
tree5b88d600a89a86689bd028207c8214e03052f089
parentd13f7d4334fc418c96c9e82a5ad2bedcde46eabe (diff)
downloadlibqmi-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.c49
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;
}