aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2009-10-12 19:51:10 -0700
committerDan Williams <dcbw@redhat.com>2009-10-12 19:51:10 -0700
commitc0253c7c293148a0bdb6c20d4b38a08401d8e34d (patch)
tree9b83b298e996037134cf74a7c5e8201bdf358012
parent6f65ad768238395a3bfc3e02fd946843282492d2 (diff)
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.
-rw-r--r--src/mm-callback-info.c23
1 files changed, 21 insertions, 2 deletions
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;