diff options
author | Dan Williams <dcbw@redhat.com> | 2009-10-12 19:51:10 -0700 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2009-10-12 19:51:10 -0700 |
commit | c0253c7c293148a0bdb6c20d4b38a08401d8e34d (patch) | |
tree | 9b83b298e996037134cf74a7c5e8201bdf358012 | |
parent | 6f65ad768238395a3bfc3e02fd946843282492d2 (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.c | 23 |
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; |