summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Suarez <gpsuarez2512@gmail.com>2014-02-05 11:12:27 -0800
committerAleksander Morgado <aleksander@aleksander.es>2014-02-06 20:19:00 +0100
commitd7823dbaebfd62cfe3a34c83346be56236194284 (patch)
treed89ed5ef03ca32b631c7ee3440fdebd84e32b559
parent6e86345af53eea76aad1afb2cc78140fe317f104 (diff)
downloadlibmbim-d7823dbaebfd62cfe3a34c83346be56236194284.tar.gz
libmbim-glib: mbim-device: Fix adding multiple timeouts for a transaction
When receiving multiple fragments device_store_transaction() is called for each fragment received thus adding a timeout callback for each fragment. A timeout callback is only removed when all fragments are received thus leaving dangling timeout callbacks. This leads to a crash when the MbimDevice is finalized. This patch checks if the transaction has already registered a timeout callback before adding a new one. Signed-off-by: Greg Suarez <gpsuarez2512@gmail.com>
-rw-r--r--src/libmbim-glib/mbim-device.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/src/libmbim-glib/mbim-device.c b/src/libmbim-glib/mbim-device.c
index d8c6f81..ef47b7e 100644
--- a/src/libmbim-glib/mbim-device.c
+++ b/src/libmbim-glib/mbim-device.c
@@ -267,21 +267,24 @@ device_store_transaction (MbimDevice *self,
tr->wait_ctx->transaction_id = tr->transaction_id;
tr->wait_ctx->type = type;
- tr->timeout_id = g_timeout_add (timeout_ms,
- (GSourceFunc)transaction_timed_out,
- tr->wait_ctx);
-
- if (tr->cancellable) {
- tr->cancellable_id = g_cancellable_connect (tr->cancellable,
- (GCallback)transaction_cancelled,
- tr->wait_ctx,
- NULL);
- if (!tr->cancellable_id) {
- g_set_error_literal (error,
- MBIM_CORE_ERROR,
- MBIM_CORE_ERROR_ABORTED,
- "Request is already cancelled");
- return FALSE;
+ /* don't add timeout if one already exists */
+ if (!tr->timeout_id) {
+ tr->timeout_id = g_timeout_add (timeout_ms,
+ (GSourceFunc)transaction_timed_out,
+ tr->wait_ctx);
+
+ if (tr->cancellable) {
+ tr->cancellable_id = g_cancellable_connect (tr->cancellable,
+ (GCallback)transaction_cancelled,
+ tr->wait_ctx,
+ NULL);
+ if (!tr->cancellable_id) {
+ g_set_error_literal (error,
+ MBIM_CORE_ERROR,
+ MBIM_CORE_ERROR_ABORTED,
+ "Request is already cancelled");
+ return FALSE;
+ }
}
}