From b13bdacf38f1dce3d914fc46472948adbf3d1bc6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 7 May 2025 22:55:57 -0500 Subject: 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 31012d26..6eb04fe2 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); } } @@ -14280,6 +14287,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); } -- cgit v1.2.3-70-g09d2