From c0253c7c293148a0bdb6c20d4b38a08401d8e34d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 12 Oct 2009 19:51:10 -0700 Subject: core: convert MMCallbackInfo modem refs to weak refs Full references prevented destruction of the modem object if it was unplugged or somehow removed. To fix that using full references on the modems would require that all usage of MMCallbackInfo to be aware of the validity of the modem and to ensure the callback was called whenever the modem became invalid. That, needless to say, would suck. Since any in-progress calls can't complete when the modem is invalid anyway, just have the MMCallbackInfo object return a generic error when the modem goes away and the call is still in-progress. --- src/mm-callback-info.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mm-callback-info.c b/src/mm-callback-info.c index bb864c5d..0aca55da 100644 --- a/src/mm-callback-info.c +++ b/src/mm-callback-info.c @@ -46,6 +46,21 @@ invoke_mm_modem_string_fn (MMCallbackInfo *info) info->error, info->user_data); } + +static void +modem_destroyed_cb (gpointer data, GObject *destroyed) +{ + MMCallbackInfo *info = data; + + info->modem = NULL; + if (!info->pending_id) { + info->error = g_error_new_literal (MM_MODEM_ERROR, + MM_MODEM_ERROR_GENERAL, + "The modem was removed or disabled."); + mm_callback_info_schedule (info); + } +} + static void callback_info_done (gpointer user_data) { @@ -60,7 +75,7 @@ callback_info_done (gpointer user_data) g_error_free (info->error); if (info->modem) - g_object_unref (info->modem); + g_object_weak_unref (G_OBJECT (info->modem), modem_destroyed_cb, info); g_datalist_clear (&info->qdata); g_slice_free (MMCallbackInfo, info); @@ -77,6 +92,9 @@ callback_info_do (gpointer user_data) void mm_callback_info_schedule (MMCallbackInfo *info) { + g_return_if_fail (info != NULL); + g_return_if_fail (info->pending_id == 0); + info->pending_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, callback_info_do, info, callback_info_done); } @@ -92,7 +110,8 @@ mm_callback_info_new_full (MMModem *modem, info = g_slice_new0 (MMCallbackInfo); g_datalist_init (&info->qdata); - info->modem = g_object_ref (modem); + info->modem = modem; + g_object_weak_ref (G_OBJECT (modem), modem_destroyed_cb, info); info->invoke_fn = invoke_fn; info->callback = callback; info->user_data = user_data; -- cgit v1.2.3-70-g09d2