aboutsummaryrefslogtreecommitdiff
path: root/src/mm-iface-modem.c
diff options
context:
space:
mode:
authorBen Chan <benchan@chromium.org>2013-12-16 16:17:38 -0800
committerAleksander Morgado <aleksander@lanedo.com>2013-12-17 01:37:13 +0100
commitab12d17bfb508e85c6b983b5d0ec8c915bd67a86 (patch)
tree2bdcf2dfdfd47b0888ede9b480cfb2217920a0bb /src/mm-iface-modem.c
parent004924b0385a503520f26e499444f8c8c42616a6 (diff)
iface-modem: fix crash in wait_for_final_state_context_complete_and_free
When wait_for_final_state_context_complete_and_free is invoked, if the callback associated with the GSimpleAsyncResult object of the WaitForFinalStateContext object updates the modem state via mm_iface_modem_update_state, state_changed is invoked, which causes wait_for_final_state_context_complete_and_free to be invoked again on the same WaitForFinalStateContext object. That leads to the following crash, which is observed sometimes when a modem is being disabled. Thread 0 *CRASHED* ( SIGSEGV @ 0x00000000 ) 0x7fcb7728f202 [libgobject-2.0.so.0.3400.3] - gobject.c:2916 g_object_unref 0x7fcb7743205c [ModemManager] - mm-broadband-modem.c:8034 disabling_context_complete_and_free 0x7fcb77434d64 [ModemManager] - mm-broadband-modem.c:8130 disabling_wait_for_final_state_ready 0x7fcb770c0b86 [libgio-2.0.so.0.3400.3] - gsimpleasyncresult.c:775 g_simple_async_result_complete 0x7fcb7740cdbc [ModemManager] - mm-iface-modem.c:101] wait_for_final_state_context_complete_and_free 0x7fcb7740ce19 [ModemManager] - mm-iface-modem.c:128] state_changed_wait_expired 0x7fcb76f78c33 [libglib-2.0.so.0.3400.3] - gmain.c:4026] g_timeout_dispatch 0x7fcb76f78087 [libglib-2.0.so.0.3400.3] - gmain.c:2715] g_main_context_dispatch 0x7fcb76f78437 [libglib-2.0.so.0.3400.3] - gmain.c:3290] g_main_context_iterate 0x7fcb76f78891 [libglib-2.0.so.0.3400.3] - gmain.c:3484] g_main_loop_run 0x7fcb773f4d55 [ModemManager] - main.c:142] main 0x7fcb7698a9c6 [libc-2.15.so] - libc-start.c:234] __libc_start_main 0x7fcb773f48b8 [ModemManager] + 0x000218b8]
Diffstat (limited to 'src/mm-iface-modem.c')
-rw-r--r--src/mm-iface-modem.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index befb0e22..868df81c 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -98,9 +98,14 @@ typedef struct {
static void
wait_for_final_state_context_complete_and_free (WaitForFinalStateContext *ctx)
{
+ /* The callback associated with 'ctx->result' may update the modem state.
+ * Disconnect the signal handler for modem state changes before completing
+ * 'ctx->result' in order to prevent state_changed from being invoked, which
+ * invokes wait_for_final_state_context_complete_and_free (ctx) again. */
+ g_signal_handler_disconnect (ctx->self, ctx->state_changed_id);
+
g_simple_async_result_complete (ctx->result);
g_object_unref (ctx->result);
- g_signal_handler_disconnect (ctx->self, ctx->state_changed_id);
g_source_remove (ctx->state_changed_wait_id);
g_object_unref (ctx->self);
g_slice_free (WaitForFinalStateContext, ctx);