base-modem: new helper method to cleanup ports during modem dispose

The different types of ports available in the modem will require
different types of cleanup actions. E.g. QMI and MBIM ports need an
explicit device close, and some other port types may need other
cleanups.
This commit is contained in:
Aleksander Morgado
2020-01-22 18:19:02 +01:00
parent 377691afd4
commit 9b56ce8ccc
+59 -32
View File
@@ -1445,6 +1445,62 @@ base_modem_cancelled (GCancellable *cancellable,
/*****************************************************************************/
static void
setup_ports_table (MMBaseModem *self)
{
g_assert (!self->priv->ports);
self->priv->ports = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
g_object_unref);
}
static void
cleanup_modem_port (MMBaseModem *self,
MMPort *port)
{
mm_dbg ("cleaning up port '%s/%s'...",
mm_port_subsys_get_string (mm_port_get_subsys (MM_PORT (port))),
mm_port_get_device (MM_PORT (port)));
#if defined WITH_MBIM
/* We need to close the MBIM port cleanly when disposing the modem object */
if (MM_IS_PORT_MBIM (port)) {
mm_port_mbim_close (MM_PORT_MBIM (port), NULL, NULL);
return;
}
#endif
#if defined WITH_QMI
/* We need to close the QMI port cleanly when disposing the modem object,
* otherwise the allocated CIDs will be kept allocated, and if we end up
* allocating too many newer allocations will fail with client-ids-exhausted
* errors. */
if (MM_IS_PORT_QMI (port)) {
mm_port_qmi_close (MM_PORT_QMI (port), NULL, NULL);
return;
}
#endif
}
static void
teardown_ports_table (MMBaseModem *self)
{
GHashTableIter iter;
gpointer value;
gpointer key;
if (!self->priv->ports)
return;
g_hash_table_iter_init (&iter, self->priv->ports);
while (g_hash_table_iter_next (&iter, &key, &value))
cleanup_modem_port (self, MM_PORT (value));
g_hash_table_destroy (g_steal_pointer (&self->priv->ports));
}
/*****************************************************************************/
static void
mm_base_modem_init (MMBaseModem *self)
{
@@ -1465,12 +1521,9 @@ mm_base_modem_init (MMBaseModem *self)
self,
NULL);
self->priv->ports = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
g_object_unref);
self->priv->max_timeouts = DEFAULT_MAX_TIMEOUTS;
setup_ports_table (self);
}
static void
@@ -1584,22 +1637,6 @@ finalize (GObject *object)
G_OBJECT_CLASS (mm_base_modem_parent_class)->finalize (object);
}
#if defined WITH_QMI
static void
foreach_port_qmi_close (MMPortQmi *port_qmi)
{
mm_port_qmi_close (port_qmi, NULL, NULL);
}
#endif
#if defined WITH_MBIM
static void
foreach_port_mbim_close (MMPortMbim *port_mbim)
{
mm_port_mbim_close (port_mbim, NULL, NULL);
}
#endif
static void
dispose (GObject *object)
{
@@ -1627,25 +1664,15 @@ dispose (GObject *object)
g_clear_object (&self->priv->gps);
g_clear_object (&self->priv->audio);
#if defined WITH_QMI
/* We need to close the QMI port cleanly when disposing the modem object,
* otherwise the allocated CIDs will be kept allocated, and if we end up
* allocating too many newer allocations will fail with client-ids-exhausted
* errors. */
g_list_foreach (self->priv->qmi, (GFunc)foreach_port_qmi_close, NULL);
g_list_free_full (self->priv->qmi, g_object_unref);
self->priv->qmi = NULL;
#endif
#if defined WITH_MBIM
/* We need to close the MBIM port cleanly when disposing the modem object */
g_list_foreach (self->priv->mbim, (GFunc)foreach_port_mbim_close, NULL);
g_list_free_full (self->priv->mbim, g_object_unref);
self->priv->mbim = NULL;
#endif
if (self->priv->ports) {
g_hash_table_destroy (self->priv->ports);
self->priv->ports = NULL;
}
teardown_ports_table (self);
g_clear_object (&self->priv->connection);