Merge request !1378 from 'suspend-bearer-timeout'
base-manager: increase suspend timeout for each active bearer https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/1378
This commit is contained in:
+21
-1
@@ -1167,6 +1167,7 @@ mm_base_manager_cleanup (MMBaseManager *self,
|
||||
GHashTableIter iter;
|
||||
MMDevice *device;
|
||||
gboolean disable, remove, low_power, terse;
|
||||
guint active_bearers = 0;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (MM_IS_BASE_MANAGER (self));
|
||||
@@ -1194,6 +1195,19 @@ mm_base_manager_cleanup (MMBaseManager *self,
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &device)) {
|
||||
DeviceCleanupContext *dctx;
|
||||
GTask *task;
|
||||
MMBaseModem *modem;
|
||||
|
||||
modem = mm_device_peek_modem (device);
|
||||
if (modem) {
|
||||
guint count = 0;
|
||||
|
||||
mm_iface_modem_count_bearers (MM_IFACE_MODEM (modem),
|
||||
MM_IFACE_MODEM_COUNT_BEARERS_FLAG_ACTIVE,
|
||||
&count,
|
||||
NULL,
|
||||
NULL);
|
||||
active_bearers += count;
|
||||
}
|
||||
|
||||
task = g_task_new (device,
|
||||
NULL,
|
||||
@@ -1201,12 +1215,18 @@ mm_base_manager_cleanup (MMBaseManager *self,
|
||||
ctx);
|
||||
ctx->tasks = g_slist_append (ctx->tasks, task);
|
||||
|
||||
dctx = device_cleanup_context_new (mm_device_peek_modem (device), flags);
|
||||
dctx = device_cleanup_context_new (modem, flags);
|
||||
g_task_set_task_data (task, dctx, (GDestroyNotify)device_cleanup_context_free);
|
||||
|
||||
device_cleanup_step (task);
|
||||
}
|
||||
|
||||
/* Increase cleanup timeout for each connected bearer; disconnecting a
|
||||
* bearer can take many seconds.
|
||||
*/
|
||||
if (active_bearers)
|
||||
mm_sleep_context_timeout_backoff (sleep_ctx, active_bearers * 20);
|
||||
|
||||
/* Complete cleanup if there were no devices */
|
||||
manager_cleanup_context_maybe_complete (ctx, NULL, NULL, FALSE);
|
||||
}
|
||||
|
||||
@@ -1459,7 +1459,8 @@ load_settings_from_bearer (MMBearerMbim *self,
|
||||
guint max_multiplexed_bearers;
|
||||
const gchar *data_port_driver;
|
||||
|
||||
if (!mm_broadband_modem_get_active_multiplexed_bearers (MM_BROADBAND_MODEM (ctx->modem),
|
||||
if (!mm_iface_modem_count_bearers (MM_IFACE_MODEM (ctx->modem),
|
||||
MM_IFACE_MODEM_COUNT_BEARERS_FLAG_MULTIPLEXED,
|
||||
¤t_multiplexed_bearers,
|
||||
&max_multiplexed_bearers,
|
||||
error))
|
||||
|
||||
+2
-1
@@ -2425,7 +2425,8 @@ load_settings_from_bearer (MMBearerQmi *self,
|
||||
guint max_multiplexed_bearers;
|
||||
gboolean multiplex_supported = TRUE;
|
||||
|
||||
if (!mm_broadband_modem_get_active_multiplexed_bearers (MM_BROADBAND_MODEM (ctx->modem),
|
||||
if (!mm_iface_modem_count_bearers (MM_IFACE_MODEM (ctx->modem),
|
||||
MM_IFACE_MODEM_COUNT_BEARERS_FLAG_MULTIPLEXED,
|
||||
¤t_multiplexed_bearers,
|
||||
&max_multiplexed_bearers,
|
||||
error))
|
||||
|
||||
@@ -13809,52 +13809,6 @@ mm_broadband_modem_get_current_charset (MMBroadbandModem *self)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
bearer_count_multiplexed_connected (MMBaseBearer *bearer,
|
||||
guint *count)
|
||||
{
|
||||
/* The Multiplexed property is only set if connected, so it's enough to check
|
||||
* that one to see if we're connected and multiplexed */
|
||||
if (mm_gdbus_bearer_get_multiplexed (MM_GDBUS_BEARER (bearer)))
|
||||
*count += 1;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mm_broadband_modem_get_active_multiplexed_bearers (MMBroadbandModem *self,
|
||||
guint *out_current,
|
||||
guint *out_max,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(MMBearerList) list = NULL;
|
||||
guint max;
|
||||
guint count = 0;
|
||||
|
||||
g_object_get (self,
|
||||
MM_IFACE_MODEM_BEARER_LIST, &list,
|
||||
NULL);
|
||||
|
||||
if (!list) {
|
||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Bearer list unavailable");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
max = mm_bearer_list_get_max_active_multiplexed (list);
|
||||
|
||||
mm_bearer_list_foreach (list,
|
||||
(MMBearerListForeachFunc)bearer_count_multiplexed_connected,
|
||||
&count);
|
||||
g_assert (!(!max && count));
|
||||
|
||||
if (out_max)
|
||||
*out_max = max;
|
||||
if (out_current)
|
||||
*out_current = count;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gchar *
|
||||
mm_broadband_modem_create_device_identifier (MMBroadbandModem *self,
|
||||
const gchar *ati,
|
||||
|
||||
@@ -135,12 +135,6 @@ gboolean mm_broadband_modem_sim_hot_swap_ports_context_init (MMBroadbandModem
|
||||
GError **error);
|
||||
void mm_broadband_modem_sim_hot_swap_ports_context_reset (MMBroadbandModem *self);
|
||||
|
||||
/* Helper to manage multiplexed bearers */
|
||||
gboolean mm_broadband_modem_get_active_multiplexed_bearers (MMBroadbandModem *self,
|
||||
guint *out_current,
|
||||
guint *out_max,
|
||||
GError **error);
|
||||
|
||||
/* Helper to manage initial EPS bearer */
|
||||
gint mm_broadband_modem_get_initial_eps_bearer_cid (MMBroadbandModem *self);
|
||||
|
||||
|
||||
@@ -6784,6 +6784,74 @@ mm_iface_modem_get_current_modes (MMIfaceModem *self,
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
const MMIfaceModemCountBearersFlags flags;
|
||||
guint count;
|
||||
} CountBearersContext;
|
||||
|
||||
static void
|
||||
bearer_count (MMBaseBearer *bearer,
|
||||
CountBearersContext *ctx)
|
||||
{
|
||||
MMBearerStatus status;
|
||||
|
||||
status = mm_base_bearer_get_status (MM_BASE_BEARER (bearer));
|
||||
|
||||
if (ctx->flags & MM_IFACE_MODEM_COUNT_BEARERS_FLAG_MULTIPLEXED) {
|
||||
/* The Multiplexed property is only set if connected, so it's enough to check
|
||||
* that one to see if we're connected and multiplexed */
|
||||
if (mm_gdbus_bearer_get_multiplexed (MM_GDBUS_BEARER (bearer)))
|
||||
ctx->count++;
|
||||
} else if (ctx->flags & MM_IFACE_MODEM_COUNT_BEARERS_FLAG_CONNECTED) {
|
||||
if (status == MM_BEARER_STATUS_CONNECTED)
|
||||
ctx->count++;
|
||||
} else if (ctx->flags & MM_IFACE_MODEM_COUNT_BEARERS_FLAG_ACTIVE) {
|
||||
if (status >= MM_BEARER_STATUS_CONNECTING)
|
||||
ctx->count++;
|
||||
} else
|
||||
ctx->count++;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mm_iface_modem_count_bearers (MMIfaceModem *self,
|
||||
MMIfaceModemCountBearersFlags flags,
|
||||
guint *out_current,
|
||||
guint *out_max,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(MMBearerList) list = NULL;
|
||||
guint max = 0;
|
||||
CountBearersContext ctx = {
|
||||
.flags = flags,
|
||||
.count = 0,
|
||||
};
|
||||
|
||||
g_object_get (self,
|
||||
MM_IFACE_MODEM_BEARER_LIST, &list,
|
||||
NULL);
|
||||
if (!list) {
|
||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Bearer list unavailable");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (flags & MM_IFACE_MODEM_COUNT_BEARERS_FLAG_MULTIPLEXED)
|
||||
max = mm_bearer_list_get_max_active_multiplexed (list);
|
||||
else
|
||||
max = mm_bearer_list_get_max_active (list);
|
||||
|
||||
mm_bearer_list_foreach (list, (MMBearerListForeachFunc)bearer_count, &ctx);
|
||||
g_assert (max >= ctx.count);
|
||||
|
||||
if (out_max)
|
||||
*out_max = max;
|
||||
if (out_current)
|
||||
*out_current = ctx.count;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
mm_iface_modem_default_init (MMIfaceModemInterface *iface)
|
||||
{
|
||||
|
||||
@@ -622,4 +622,19 @@ void mm_iface_modem_process_sim_event (MMIfaceModem *self);
|
||||
|
||||
gboolean mm_iface_modem_is_primary_sim_slot_switch_ongoing (MMIfaceModem *self);
|
||||
|
||||
typedef enum {
|
||||
/* Connecting or connected bearers */
|
||||
MM_IFACE_MODEM_COUNT_BEARERS_FLAG_ACTIVE = 0x1,
|
||||
/* Fully connected bearers */
|
||||
MM_IFACE_MODEM_COUNT_BEARERS_FLAG_CONNECTED = 0x2,
|
||||
/* Multiplexed implies connected */
|
||||
MM_IFACE_MODEM_COUNT_BEARERS_FLAG_MULTIPLEXED = 0x4,
|
||||
} MMIfaceModemCountBearersFlags;
|
||||
|
||||
gboolean mm_iface_modem_count_bearers (MMIfaceModem *self,
|
||||
MMIfaceModemCountBearersFlags flags,
|
||||
guint *out_current,
|
||||
guint *out_max,
|
||||
GError **error);
|
||||
|
||||
#endif /* MM_IFACE_MODEM_H */
|
||||
|
||||
+30
-3
@@ -27,6 +27,7 @@ G_DEFINE_TYPE_EXTENDED (MMSleepContext, mm_sleep_context, G_TYPE_OBJECT, 0,
|
||||
struct _MMSleepContextPrivate {
|
||||
GTask *task;
|
||||
guint timeout_id;
|
||||
gint64 timeout_start;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -52,6 +53,7 @@ timeout_cleanup (MMSleepContext *self)
|
||||
if (self->priv->timeout_id)
|
||||
g_source_remove (self->priv->timeout_id);
|
||||
self->priv->timeout_id = 0;
|
||||
self->priv->timeout_start = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -95,6 +97,33 @@ operation_ready (MMSleepContext *self,
|
||||
g_signal_emit (self, signals[DONE], 0, error);
|
||||
}
|
||||
|
||||
static void
|
||||
timeout_add (MMSleepContext *self,
|
||||
guint interval)
|
||||
{
|
||||
timeout_cleanup (self);
|
||||
self->priv->timeout_start = g_get_monotonic_time ();
|
||||
self->priv->timeout_id = g_timeout_add_seconds (interval,
|
||||
(GSourceFunc)operation_timeout,
|
||||
self);
|
||||
}
|
||||
|
||||
void
|
||||
mm_sleep_context_timeout_backoff (MMSleepContext *self,
|
||||
guint more_seconds)
|
||||
{
|
||||
gint64 cur_time;
|
||||
gint64 new_interval;
|
||||
|
||||
new_interval = more_seconds * G_USEC_PER_SEC;
|
||||
if (self->priv->timeout_start) {
|
||||
cur_time = g_get_monotonic_time ();
|
||||
new_interval += (cur_time - self->priv->timeout_start);
|
||||
}
|
||||
|
||||
timeout_add (self, new_interval / G_USEC_PER_SEC);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
MMSleepContext *
|
||||
@@ -107,9 +136,7 @@ mm_sleep_context_new (guint timeout_seconds)
|
||||
NULL,
|
||||
(GAsyncReadyCallback)operation_ready,
|
||||
NULL);
|
||||
self->priv->timeout_id = g_timeout_add_seconds (timeout_seconds,
|
||||
(GSourceFunc)operation_timeout,
|
||||
self);
|
||||
timeout_add (self, timeout_seconds);
|
||||
mm_obj_dbg (self, "new context with %d second timeout", timeout_seconds);
|
||||
|
||||
return self;
|
||||
|
||||
@@ -51,6 +51,9 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMSleepContext, g_object_unref)
|
||||
|
||||
MMSleepContext *mm_sleep_context_new (guint timeout_seconds);
|
||||
|
||||
void mm_sleep_context_timeout_backoff (MMSleepContext *self,
|
||||
guint more_seconds);
|
||||
|
||||
/* The MMSleepContext assumes ownership of @error */
|
||||
void mm_sleep_context_complete (MMSleepContext *self,
|
||||
GError *error);
|
||||
|
||||
Reference in New Issue
Block a user