suspend: invalidate and remove modems on suspend, reprobe on resume
This commit is contained in:
@@ -157,11 +157,16 @@ if test "x$with_suspend_resume" = "x"; then
|
||||
fi
|
||||
|
||||
case $with_suspend_resume in
|
||||
none) ;;
|
||||
upower) ;;
|
||||
none)
|
||||
AC_DEFINE(WITH_SUSPEND_RESUME, 0, [Define if you have suspend-resume support])
|
||||
;;
|
||||
upower)
|
||||
AC_DEFINE(WITH_SUSPEND_RESUME, 1, [Define if you have suspend-resume support])
|
||||
;;
|
||||
systemd)
|
||||
PKG_CHECK_MODULES(SYSTEMD_INHIBIT, [libsystemd >= 209],,
|
||||
[PKG_CHECK_MODULES(SYSTEMD_INHIBIT, [libsystemd-login >= 183])])
|
||||
AC_DEFINE(WITH_SUSPEND_RESUME, 1, [Define if you have suspend-resume support])
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR(--with-suspend-resume must be one of [none, upower, systemd])
|
||||
|
33
src/main.c
33
src/main.c
@@ -30,6 +30,10 @@
|
||||
#include "mm-log.h"
|
||||
#include "mm-context.h"
|
||||
|
||||
#if WITH_SUSPEND_RESUME
|
||||
# include "mm-sleep-monitor.h"
|
||||
#endif
|
||||
|
||||
/* Maximum time to wait for all modems to get disabled and removed */
|
||||
#define MAX_SHUTDOWN_TIME_SECS 20
|
||||
|
||||
@@ -51,6 +55,24 @@ quit_cb (gpointer user_data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if WITH_SUSPEND_RESUME
|
||||
|
||||
static void
|
||||
sleeping_cb (MMSleepMonitor *sleep_monitor)
|
||||
{
|
||||
mm_dbg ("Removing devices... (sleeping)");
|
||||
mm_base_manager_shutdown (manager, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
resuming_cb (MMSleepMonitor *sleep_monitor)
|
||||
{
|
||||
mm_dbg ("Re-scanning (resuming)");
|
||||
mm_base_manager_start (manager, FALSE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
bus_acquired_cb (GDBusConnection *connection,
|
||||
const gchar *name,
|
||||
@@ -144,6 +166,15 @@ main (int argc, char *argv[])
|
||||
name_lost_cb,
|
||||
NULL,
|
||||
NULL);
|
||||
#if WITH_SUSPEND_RESUME
|
||||
{
|
||||
MMSleepMonitor *sleep_monitor;
|
||||
|
||||
sleep_monitor = mm_sleep_monitor_get ();
|
||||
g_signal_connect (sleep_monitor, MM_SLEEP_MONITOR_SLEEPING, G_CALLBACK (sleeping_cb), NULL);
|
||||
g_signal_connect (sleep_monitor, MM_SLEEP_MONITOR_RESUMING, G_CALLBACK (resuming_cb), NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Go into the main loop */
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
@@ -157,7 +188,7 @@ main (int argc, char *argv[])
|
||||
if (manager) {
|
||||
GTimer *timer;
|
||||
|
||||
mm_base_manager_shutdown (manager);
|
||||
mm_base_manager_shutdown (manager, TRUE);
|
||||
|
||||
/* Wait for all modems to be disabled and removed, but don't wait
|
||||
* forever: if disabling the modems takes longer than 20s, just
|
||||
|
@@ -538,6 +538,7 @@ remove_disable_ready (MMBaseModem *modem,
|
||||
|
||||
device = find_device_by_modem (self, modem);
|
||||
if (device) {
|
||||
g_cancellable_cancel (mm_base_modem_peek_cancellable (modem));
|
||||
mm_device_remove_modem (device);
|
||||
g_hash_table_remove (self->priv->devices, device);
|
||||
}
|
||||
@@ -555,8 +556,23 @@ foreach_disable (gpointer key,
|
||||
mm_base_modem_disable (modem, (GAsyncReadyCallback)remove_disable_ready, self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
foreach_remove (gpointer key,
|
||||
MMDevice *device,
|
||||
MMBaseManager *self)
|
||||
{
|
||||
MMBaseModem *modem;
|
||||
|
||||
modem = mm_device_peek_modem (device);
|
||||
if (modem)
|
||||
g_cancellable_cancel (mm_base_modem_peek_cancellable (modem));
|
||||
mm_device_remove_modem (device);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
mm_base_manager_shutdown (MMBaseManager *self)
|
||||
mm_base_manager_shutdown (MMBaseManager *self,
|
||||
gboolean disable)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (MM_IS_BASE_MANAGER (self));
|
||||
@@ -564,12 +580,18 @@ mm_base_manager_shutdown (MMBaseManager *self)
|
||||
/* Cancel all ongoing auth requests */
|
||||
g_cancellable_cancel (self->priv->authp_cancellable);
|
||||
|
||||
if (disable) {
|
||||
g_hash_table_foreach (self->priv->devices, (GHFunc)foreach_disable, self);
|
||||
|
||||
/* Disabling may take a few iterations of the mainloop, so the caller
|
||||
* has to iterate the mainloop until all devices have been disabled and
|
||||
* removed.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise, just remove directly */
|
||||
g_hash_table_foreach_remove (self->priv->devices, (GHRFunc)foreach_remove, self);
|
||||
}
|
||||
|
||||
guint32
|
||||
|
@@ -57,7 +57,8 @@ MMBaseManager *mm_base_manager_new (GDBusConnection *bus,
|
||||
void mm_base_manager_start (MMBaseManager *manager,
|
||||
gboolean manual_scan);
|
||||
|
||||
void mm_base_manager_shutdown (MMBaseManager *manager);
|
||||
void mm_base_manager_shutdown (MMBaseManager *manager,
|
||||
gboolean disable);
|
||||
|
||||
guint32 mm_base_manager_num_modems (MMBaseManager *manager);
|
||||
|
||||
|
Reference in New Issue
Block a user