From dae00a9f2f5184cc8025051c4c75d09ca29a2635 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 7 May 2025 22:55:57 -0500 Subject: [PATCH] broadband-modem: close serial ports in dispose We want ports to be closed as early as possible; so make sure they are closed in dispose() which is run explicitly by MMDevice when cleaning up and removing the modem. Otherwise they could stay open longer than we want, causing problems for suspend/resume. This caused problems with suspend because cancelling the MMBaseModem's cancellable triggered an idle handler that held a reference to the modem, preventing finalize() from running until after the suspend code was finished, thus preventing ports from being closed and cleaned up. Closing them in dispose() handles this. Signed-off-by: Dan Williams --- src/mm-broadband-modem.c | 44 ++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index 5e026449..407b6622 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -323,25 +323,32 @@ ports_context_ref (PortsContext *ctx) return ctx; } +static void +ports_context_dispose (PortsContext *ctx) +{ + if (ctx->primary && ctx->primary_open) { + mm_port_serial_close (MM_PORT_SERIAL (ctx->primary)); + ctx->primary_open = FALSE; + } + if (ctx->secondary && ctx->secondary_open) { + mm_port_serial_close (MM_PORT_SERIAL (ctx->secondary)); + ctx->secondary_open = FALSE; + } + if (ctx->qcdm && ctx->qcdm_open) { + mm_port_serial_close (MM_PORT_SERIAL (ctx->qcdm)); + ctx->qcdm_open = FALSE; + } +} + static void ports_context_unref (PortsContext *ctx) { if (g_atomic_int_dec_and_test (&ctx->ref_count)) { - if (ctx->primary) { - if (ctx->primary_open) - mm_port_serial_close (MM_PORT_SERIAL (ctx->primary)); - g_object_unref (ctx->primary); - } - if (ctx->secondary) { - if (ctx->secondary_open) - mm_port_serial_close (MM_PORT_SERIAL (ctx->secondary)); - g_object_unref (ctx->secondary); - } - if (ctx->qcdm) { - if (ctx->qcdm_open) - mm_port_serial_close (MM_PORT_SERIAL (ctx->qcdm)); - g_object_unref (ctx->qcdm); - } + ports_context_dispose (ctx); + g_clear_object (&ctx->primary); + g_clear_object (&ctx->secondary); + g_clear_object (&ctx->qcdm); + g_free (ctx); } } @@ -14258,6 +14265,13 @@ dispose (GObject *object) g_clear_object (&self->priv->modem_simple_status); g_clear_object (&self->priv->modem_cell_broadcast_cbm_list); + if (self->priv->enabled_ports_ctx) + ports_context_dispose (self->priv->enabled_ports_ctx); + if (self->priv->sim_hot_swap_ports_ctx) + ports_context_dispose (self->priv->sim_hot_swap_ports_ctx); + if (self->priv->in_call_ports_ctx) + ports_context_dispose (self->priv->in_call_ports_ctx); + G_OBJECT_CLASS (mm_broadband_modem_parent_class)->dispose (object); }