[PATCH] device: disconnect signal handlers when modem object removed

Aleksander Morgado aleksander at aleksander.es
Mon Feb 13 14:06:56 UTC 2017


Don't rely on the automatic disconnection of the signal as the last
reference of the modem object may outlive the device object.

Also, setup a common clear_modem() function to dispose the internal
reference of the modem object, which will take care of the signal
disconnection when required.

https://lists.freedesktop.org/archives/modemmanager-devel/2017-February/003907.html
---

What do you think of this?

---
 src/mm-device.c | 35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/src/mm-device.c b/src/mm-device.c
index 6750a0b1..20fb9578 100644
--- a/src/mm-device.c
+++ b/src/mm-device.c
@@ -71,6 +71,7 @@ struct _MMDevicePrivate {

     /* The Modem object for this device */
     MMBaseModem *modem;
+    gulong       modem_valid_id;

     /* When exported, a reference to the object manager */
     GDBusObjectManagerServer *object_manager;
@@ -293,6 +294,21 @@ export_modem (MMDevice *self)

 /*****************************************************************************/

+static void
+clear_modem (MMDevice *self)
+{
+    if (self->priv->modem_valid_id) {
+        if (self->priv->modem && g_signal_handler_is_connected (self->priv->modem, self->priv->modem_valid_id))
+            g_signal_handler_disconnect (self->priv->modem, self->priv->modem_valid_id);
+        self->priv->modem_valid_id = 0;
+    }
+
+    /* Run dispose before unref-ing, in order to cleanup the SIM object,
+     * if any (which also holds a reference to the modem object) */
+    g_object_run_dispose (G_OBJECT (self->priv->modem));
+    g_clear_object (&(self->priv->modem));
+}
+
 void
 mm_device_remove_modem (MMDevice  *self)
 {
@@ -300,11 +316,7 @@ mm_device_remove_modem (MMDevice  *self)
         return;

     unexport_modem (self);
-
-    /* Run dispose before unref-ing, in order to cleanup the SIM object,
-     * if any (which also holds a reference to the modem object) */
-    g_object_run_dispose (G_OBJECT (self->priv->modem));
-    g_clear_object (&(self->priv->modem));
+    clear_modem (self);
     g_clear_object (&(self->priv->object_manager));
 }

@@ -391,10 +403,10 @@ mm_device_create_modem (MMDevice                  *self,
         self->priv->object_manager = g_object_ref (object_manager);

         /* We want to get notified when the modem becomes valid/invalid */
-        g_signal_connect (self->priv->modem,
-                          "notify::" MM_BASE_MODEM_VALID,
-                          G_CALLBACK (modem_valid),
-                          self);
+        self->priv->modem_valid_id = g_signal_connect (self->priv->modem,
+                                                       "notify::" MM_BASE_MODEM_VALID,
+                                                       G_CALLBACK (modem_valid),
+                                                       self);
     }

     return !!self->priv->modem;
@@ -582,7 +594,7 @@ set_property (GObject *object,
         self->priv->plugin = g_value_dup_object (value);
         break;
     case PROP_MODEM:
-        g_clear_object (&(self->priv->modem));
+        clear_modem (self);
         self->priv->modem = g_value_dup_object (value);
         break;
     case PROP_HOTPLUGGED:
@@ -635,7 +647,8 @@ dispose (GObject *object)
     g_clear_object (&(self->priv->plugin));
     g_list_free_full (self->priv->port_probes, (GDestroyNotify)g_object_unref);
     g_list_free_full (self->priv->ignored_port_probes, (GDestroyNotify)g_object_unref);
-    g_clear_object (&(self->priv->modem));
+
+    clear_modem (self);

     G_OBJECT_CLASS (mm_device_parent_class)->dispose (object);
 }
--
2.11.1


More information about the ModemManager-devel mailing list