aboutsummaryrefslogtreecommitdiff
path: root/src/mm-port-mbim.c
diff options
context:
space:
mode:
authorAleksander Morgado <aleksandermj@chromium.org>2022-12-15 21:57:57 +0000
committerAleksander Morgado <aleksandermj@chromium.org>2022-12-18 21:54:58 +0000
commit309a8a515bf922b679f36971bffc2999bdc6e293 (patch)
treed0d727020ff5eb83604f4f9bcd6bc62810feabb1 /src/mm-port-mbim.c
parenta20f2428eea3fa6fd83edeb5f1a844926b4a5b1c (diff)
port-mbim: implement the new generic 'removed' signal
Letting the MMBroadbandModemMbim listen for the notifications of the MbimDevice was not a good idea, especially since no explicit reference to the device object was hold in the modem object. This leads to race conditions in which the MbimDevice outlives the MMBroadbandModemMbim and the MMPortMbim, and when the "device-removed" signal is triggered, the program crashes. The MMPortMbim will now emit its own 'removed' signals when the underlying MbimDevice emits "device-removed', ensuring that the signal handler is properly cleared up during the MMPortMbim disposal. Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/518
Diffstat (limited to 'src/mm-port-mbim.c')
-rw-r--r--src/mm-port-mbim.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/mm-port-mbim.c b/src/mm-port-mbim.c
index 7dcdda59..ae1021a0 100644
--- a/src/mm-port-mbim.c
+++ b/src/mm-port-mbim.c
@@ -35,8 +35,9 @@ struct _MMPortMbimPrivate {
gboolean in_progress;
MbimDevice *mbim_device;
- /* timeout monitoring */
+ /* monitoring */
gulong timeout_monitoring_id;
+ gulong removed_monitoring_id;
#if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED
gboolean qmi_supported;
@@ -392,13 +393,17 @@ mm_port_mbim_reset (MMPortMbim *self,
/*****************************************************************************/
static void
-reset_timeout_monitoring (MMPortMbim *self,
- MbimDevice *mbim_device)
+reset_monitoring (MMPortMbim *self,
+ MbimDevice *mbim_device)
{
if (self->priv->timeout_monitoring_id && mbim_device) {
g_signal_handler_disconnect (mbim_device, self->priv->timeout_monitoring_id);
self->priv->timeout_monitoring_id = 0;
}
+ if (self->priv->removed_monitoring_id && mbim_device) {
+ g_signal_handler_disconnect (mbim_device, self->priv->removed_monitoring_id);
+ self->priv->removed_monitoring_id = 0;
+ }
}
static void
@@ -410,18 +415,30 @@ consecutive_timeouts_updated_cb (MMPortMbim *self,
}
static void
-setup_timeout_monitoring (MMPortMbim *self,
- MbimDevice *mbim_device)
+device_removed_cb (MMPortMbim *self)
+{
+ g_signal_emit_by_name (self, MM_PORT_SIGNAL_REMOVED);
+}
+
+static void
+setup_monitoring (MMPortMbim *self,
+ MbimDevice *mbim_device)
{
g_assert (mbim_device);
- reset_timeout_monitoring (self, mbim_device);
+ reset_monitoring (self, mbim_device);
g_assert (!self->priv->timeout_monitoring_id);
self->priv->timeout_monitoring_id = g_signal_connect_swapped (mbim_device,
"notify::" MBIM_DEVICE_CONSECUTIVE_TIMEOUTS,
G_CALLBACK (consecutive_timeouts_updated_cb),
self);
+
+ g_assert (!self->priv->removed_monitoring_id);
+ self->priv->removed_monitoring_id = g_signal_connect_swapped (mbim_device,
+ MBIM_DEVICE_SIGNAL_REMOVED,
+ G_CALLBACK (device_removed_cb),
+ self);
}
/*****************************************************************************/
@@ -600,7 +617,7 @@ mbim_device_open_ready (MbimDevice *mbim_device,
}
mm_obj_dbg (self, "MBIM device is now open");
- setup_timeout_monitoring (self, mbim_device);
+ setup_monitoring (self, mbim_device);
#if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED
if (self->priv->qmi_supported) {
@@ -739,7 +756,7 @@ mbim_device_close_ready (MbimDevice *mbim_device,
g_assert (!self->priv->mbim_device);
self->priv->in_progress = FALSE;
- reset_timeout_monitoring (self, mbim_device);
+ reset_monitoring (self, mbim_device);
if (!mbim_device_close_finish (mbim_device, res, &error))
g_task_return_error (task, error);
@@ -896,7 +913,7 @@ dispose (GObject *object)
#endif
/* Clear device object */
- reset_timeout_monitoring (self, self->priv->mbim_device);
+ reset_monitoring (self, self->priv->mbim_device);
g_clear_object (&self->priv->mbim_device);
G_OBJECT_CLASS (mm_port_mbim_parent_class)->dispose (object);