summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2015-01-16 09:52:05 +0100
committerAleksander Morgado <aleksander@aleksander.es>2015-01-16 09:52:05 +0100
commitd5d100bf8d2d885c13026cbaeb18430c8a362f71 (patch)
tree70408058b4189fd82795a99cafbb3880b3f9fe22
parentd13e248cf70196f6ca16fb9e46546d51243bc967 (diff)
downloadModemManager-aleksander/suspend-resume.tar.gz
suspend: invalidate and remove modems on suspend, reprobe on resumealeksander/suspend-resume
-rw-r--r--configure.ac9
-rw-r--r--src/main.c33
-rw-r--r--src/mm-base-manager.c34
-rw-r--r--src/mm-base-manager.h3
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);