suspend: invalidate and remove modems on suspend, reprobe on resume

This commit is contained in:
Aleksander Morgado
2015-01-16 09:52:05 +01:00
parent 132fbb0a7f
commit b6f8e5f08d
4 changed files with 69 additions and 10 deletions

View File

@@ -157,11 +157,16 @@ if test "x$with_suspend_resume" = "x"; then
fi fi
case $with_suspend_resume in case $with_suspend_resume in
none) ;; none)
upower) ;; 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) systemd)
PKG_CHECK_MODULES(SYSTEMD_INHIBIT, [libsystemd >= 209],, PKG_CHECK_MODULES(SYSTEMD_INHIBIT, [libsystemd >= 209],,
[PKG_CHECK_MODULES(SYSTEMD_INHIBIT, [libsystemd-login >= 183])]) [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]) AC_MSG_ERROR(--with-suspend-resume must be one of [none, upower, systemd])

View File

@@ -30,6 +30,10 @@
#include "mm-log.h" #include "mm-log.h"
#include "mm-context.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 */ /* Maximum time to wait for all modems to get disabled and removed */
#define MAX_SHUTDOWN_TIME_SECS 20 #define MAX_SHUTDOWN_TIME_SECS 20
@@ -51,6 +55,24 @@ quit_cb (gpointer user_data)
return FALSE; 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 static void
bus_acquired_cb (GDBusConnection *connection, bus_acquired_cb (GDBusConnection *connection,
const gchar *name, const gchar *name,
@@ -144,6 +166,15 @@ main (int argc, char *argv[])
name_lost_cb, name_lost_cb,
NULL, NULL,
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 */ /* Go into the main loop */
loop = g_main_loop_new (NULL, FALSE); loop = g_main_loop_new (NULL, FALSE);
@@ -157,7 +188,7 @@ main (int argc, char *argv[])
if (manager) { if (manager) {
GTimer *timer; 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 /* Wait for all modems to be disabled and removed, but don't wait
* forever: if disabling the modems takes longer than 20s, just * forever: if disabling the modems takes longer than 20s, just

View File

@@ -538,6 +538,7 @@ remove_disable_ready (MMBaseModem *modem,
device = find_device_by_modem (self, modem); device = find_device_by_modem (self, modem);
if (device) { if (device) {
g_cancellable_cancel (mm_base_modem_peek_cancellable (modem));
mm_device_remove_modem (device); mm_device_remove_modem (device);
g_hash_table_remove (self->priv->devices, 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); 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 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 (self != NULL);
g_return_if_fail (MM_IS_BASE_MANAGER (self)); g_return_if_fail (MM_IS_BASE_MANAGER (self));
@@ -564,12 +580,18 @@ mm_base_manager_shutdown (MMBaseManager *self)
/* Cancel all ongoing auth requests */ /* Cancel all ongoing auth requests */
g_cancellable_cancel (self->priv->authp_cancellable); 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 /* Disabling may take a few iterations of the mainloop, so the caller
* has to iterate the mainloop until all devices have been disabled and * has to iterate the mainloop until all devices have been disabled and
* removed. * removed.
*/ */
return;
}
/* Otherwise, just remove directly */
g_hash_table_foreach_remove (self->priv->devices, (GHRFunc)foreach_remove, self);
} }
guint32 guint32

View File

@@ -57,7 +57,8 @@ MMBaseManager *mm_base_manager_new (GDBusConnection *bus,
void mm_base_manager_start (MMBaseManager *manager, void mm_base_manager_start (MMBaseManager *manager,
gboolean manual_scan); 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); guint32 mm_base_manager_num_modems (MMBaseManager *manager);