diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2015-01-16 09:52:05 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2015-01-16 09:52:05 +0100 |
commit | d5d100bf8d2d885c13026cbaeb18430c8a362f71 (patch) | |
tree | 70408058b4189fd82795a99cafbb3880b3f9fe22 | |
parent | d13e248cf70196f6ca16fb9e46546d51243bc967 (diff) | |
download | ModemManager-aleksander/suspend-resume.tar.gz |
suspend: invalidate and remove modems on suspend, reprobe on resumealeksander/suspend-resume
-rw-r--r-- | configure.ac | 9 | ||||
-rw-r--r-- | src/main.c | 33 | ||||
-rw-r--r-- | src/mm-base-manager.c | 34 | ||||
-rw-r--r-- | src/mm-base-manager.h | 3 |
4 files changed, 69 insertions, 10 deletions
diff --git a/configure.ac b/configure.ac index 49a950249..dd9b112bd 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/src/main.c b/src/main.c index 47fa61357..8a3ebaba5 100644 --- a/src/main.c +++ b/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 diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c index f5d4e2861..3b9f34d43 100644 --- a/src/mm-base-manager.c +++ b/src/mm-base-manager.c @@ -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); - g_hash_table_foreach (self->priv->devices, (GHFunc)foreach_disable, self); + 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. - */ + /* 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 diff --git a/src/mm-base-manager.h b/src/mm-base-manager.h index 0e4e97bd6..43e7cae03 100644 --- a/src/mm-base-manager.h +++ b/src/mm-base-manager.h @@ -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); |