summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-03-07 13:04:35 +0100
committerAleksander Morgado <aleksander@lanedo.com>2012-03-07 14:24:27 +0100
commit40cb0d15eb2c28c18395aa5efd2f0c40ba49f61b (patch)
tree4471bd6a114450fbaedc700514ebaf251a766f15
parent3a73e7718f66e24be0761649147bbca264454f86 (diff)
downloadModemManager-40cb0d15eb2c28c18395aa5efd2f0c40ba49f61b.tar.gz
serial-port: allow cancelling the response timeout
-rw-r--r--src/mm-at-serial-port.c2
-rw-r--r--src/mm-qcdm-serial-port.c2
-rw-r--r--src/mm-serial-port.c62
-rw-r--r--src/mm-serial-port.h4
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 */
-