diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2012-03-07 13:04:35 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-03-07 14:24:27 +0100 |
commit | 40cb0d15eb2c28c18395aa5efd2f0c40ba49f61b (patch) | |
tree | 4471bd6a114450fbaedc700514ebaf251a766f15 | |
parent | 3a73e7718f66e24be0761649147bbca264454f86 (diff) | |
download | ModemManager-40cb0d15eb2c28c18395aa5efd2f0c40ba49f61b.tar.gz |
serial-port: allow cancelling the response timeout
-rw-r--r-- | src/mm-at-serial-port.c | 2 | ||||
-rw-r--r-- | src/mm-qcdm-serial-port.c | 2 | ||||
-rw-r--r-- | src/mm-serial-port.c | 62 | ||||
-rw-r--r-- | src/mm-serial-port.h | 4 |
4 files changed, 67 insertions, 3 deletions
diff --git a/src/mm-at-serial-port.c b/src/mm-at-serial-port.c index dfc18085f..2ceb59c1d 100644 --- a/src/mm-at-serial-port.c +++ b/src/mm-at-serial-port.c @@ -286,6 +286,7 @@ mm_at_serial_port_queue_command (MMAtSerialPort *self, buf, TRUE, timeout_seconds, + NULL, (MMSerialResponseFn) callback, user_data); } @@ -310,6 +311,7 @@ mm_at_serial_port_queue_command_cached (MMAtSerialPort *self, buf, TRUE, timeout_seconds, + NULL, (MMSerialResponseFn) callback, user_data); } diff --git a/src/mm-qcdm-serial-port.c b/src/mm-qcdm-serial-port.c index 5812ff019..8dc50cb47 100644 --- a/src/mm-qcdm-serial-port.c +++ b/src/mm-qcdm-serial-port.c @@ -157,6 +157,7 @@ mm_qcdm_serial_port_queue_command (MMQcdmSerialPort *self, command, TRUE, timeout_seconds, + NULL, (MMSerialResponseFn) callback, user_data); } @@ -177,6 +178,7 @@ mm_qcdm_serial_port_queue_command_cached (MMQcdmSerialPort *self, command, TRUE, timeout_seconds, + NULL, (MMSerialResponseFn) callback, user_data); } diff --git a/src/mm-serial-port.c b/src/mm-serial-port.c index 7c69fcf79..09c9ec844 100644 --- a/src/mm-serial-port.c +++ b/src/mm-serial-port.c @@ -89,6 +89,9 @@ typedef struct { guint watch_id; guint timeout_id; + GCancellable *cancellable; + gulong cancellable_id; + guint n_consecutive_timeouts; guint flash_id; @@ -105,6 +108,7 @@ typedef struct { gpointer user_data; guint32 timeout; gboolean cached; + GCancellable *cancellable; } MMQueueData; #if 0 @@ -563,6 +567,15 @@ mm_serial_port_got_response (MMSerialPort *self, GError *error) priv->timeout_id = 0; } + if (priv->cancellable_id) { + g_assert (priv->cancellable != NULL); + g_cancellable_disconnect (priv->cancellable, + priv->cancellable_id); + priv->cancellable_id = 0; + } + + g_clear_object (&priv->cancellable); + info = (MMQueueData *) g_queue_pop_head (priv->queue); if (info) { if (info->cached && !error) @@ -577,6 +590,7 @@ mm_serial_port_got_response (MMSerialPort *self, GError *error) info->user_data); } + g_clear_object (&info->cancellable); g_byte_array_free (info->command, TRUE); g_slice_free (MMQueueData, info); } @@ -618,6 +632,26 @@ mm_serial_port_timed_out (gpointer data) return FALSE; } +static void +serial_port_response_wait_cancelled (GCancellable *cancellable, + MMSerialPort *self) +{ + MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self); + GError *error; + + /* We don't want to call disconnect () while in the signal handler */ + priv->cancellable_id = 0; + + error = g_error_new_literal (MM_CORE_ERROR, + MM_CORE_ERROR_CANCELLED, + "Waiting for the reply cancelled"); + + /* FIXME: This is not completely correct - if the response finally arrives and there's + some other command waiting for response right now, the other command will + get the output of the cancelled command. Not sure what to do here. */ + mm_serial_port_got_response (self, error); +} + static gboolean mm_serial_port_queue_process (gpointer data) { @@ -655,6 +689,23 @@ mm_serial_port_queue_process (gpointer data) if (mm_serial_port_process_command (self, info, &error)) { if (info->done) { + /* setup the cancellable so that we can stop waiting for a response */ + if (info->cancellable) { + priv->cancellable = g_object_ref (info->cancellable); + priv->cancellable_id = (g_cancellable_connect ( + info->cancellable, + (GCallback) serial_port_response_wait_cancelled, + self, + NULL)); + if (!priv->cancellable_id) { + error = g_error_new (MM_CORE_ERROR, + MM_CORE_ERROR_CANCELLED, + "Won't wait for the reply"); + mm_serial_port_got_response (self, error); + return FALSE; + } + } + /* If the command is finished being sent, schedule the timeout */ priv->timeout_id = g_timeout_add_seconds (info->timeout, mm_serial_port_timed_out, @@ -978,6 +1029,7 @@ mm_serial_port_close (MMSerialPort *self) g_byte_array_free (response, TRUE); } + g_clear_object (&item->cancellable); g_byte_array_free (item->command, TRUE); g_slice_free (MMQueueData, item); } @@ -992,6 +1044,8 @@ mm_serial_port_close (MMSerialPort *self) g_source_remove (priv->queue_id); priv->queue_id = 0; } + + g_clear_object (&priv->cancellable); } void @@ -1016,6 +1070,7 @@ internal_queue_command (MMSerialPort *self, gboolean take_command, gboolean cached, guint32 timeout_seconds, + GCancellable *cancellable, MMSerialResponseFn callback, gpointer user_data) { @@ -1050,6 +1105,7 @@ internal_queue_command (MMSerialPort *self, info->cached = cached; info->timeout = timeout_seconds; + info->cancellable = (cancellable ? g_object_ref (cancellable) : NULL); info->callback = (GCallback) callback; info->user_data = user_data; @@ -1068,10 +1124,11 @@ mm_serial_port_queue_command (MMSerialPort *self, GByteArray *command, gboolean take_command, guint32 timeout_seconds, + GCancellable *cancellable, MMSerialResponseFn callback, gpointer user_data) { - internal_queue_command (self, command, take_command, FALSE, timeout_seconds, callback, user_data); + internal_queue_command (self, command, take_command, FALSE, timeout_seconds, cancellable, callback, user_data); } void @@ -1079,10 +1136,11 @@ mm_serial_port_queue_command_cached (MMSerialPort *self, GByteArray *command, gboolean take_command, guint32 timeout_seconds, + GCancellable *cancellable, MMSerialResponseFn callback, gpointer user_data) { - internal_queue_command (self, command, take_command, TRUE, timeout_seconds, callback, user_data); + internal_queue_command (self, command, take_command, TRUE, timeout_seconds, cancellable, callback, user_data); } static gboolean diff --git a/src/mm-serial-port.h b/src/mm-serial-port.h index 9450926f3..843cea8e3 100644 --- a/src/mm-serial-port.h +++ b/src/mm-serial-port.h @@ -19,6 +19,7 @@ #include <glib.h> #include <glib-object.h> +#include <gio/gio.h> #include "mm-port.h" @@ -132,6 +133,7 @@ void mm_serial_port_queue_command (MMSerialPort *self, GByteArray *command, gboolean take_command, guint32 timeout_seconds, + GCancellable *cancellable, MMSerialResponseFn callback, gpointer user_data); @@ -139,8 +141,8 @@ void mm_serial_port_queue_command_cached (MMSerialPort *self, GByteArray *command, gboolean take_command, guint32 timeout_seconds, + GCancellable *cancellable, MMSerialResponseFn callback, gpointer user_data); #endif /* MM_SERIAL_PORT_H */ - |