diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2016-05-05 11:22:14 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2016-05-13 14:34:53 +0200 |
commit | 69ab984fed80c70d1937684ee1884bd53ca6551f (patch) | |
tree | 2edd67103dc2615ba124186a9f090538cb8e5948 | |
parent | 31c2e0b57c96dc4779d9e62db7b101560cb476d8 (diff) | |
download | NetworkManager-69ab984fed80c70d1937684ee1884bd53ca6551f.tar.gz |
sleep-monitor: add functions for delaying the suspension
To allow the execution of asynchronous actions before the system is
suspended, add a mechanism for delaying the drop of inhibitor lock.
Clients can supend the suspension by calling inhibit_take() in their
handler for SLEEPING signal and use inhibit_release() later when they
are done.
We take a "delay" type inhibitor lock, which means that the system
will proceed anyway after a certain amount of time.
Co-Authored-By: Thomas Haller <thaller@redhat.com>
-rw-r--r-- | src/nm-sleep-monitor.c | 70 | ||||
-rw-r--r-- | src/nm-sleep-monitor.h | 6 |
2 files changed, 71 insertions, 5 deletions
diff --git a/src/nm-sleep-monitor.c b/src/nm-sleep-monitor.c index 42a61f6fe3..13ce1be000 100644 --- a/src/nm-sleep-monitor.c +++ b/src/nm-sleep-monitor.c @@ -73,6 +73,8 @@ struct _NMSleepMonitor { GCancellable *cancellable; gint inhibit_fd; + GSList *handles_active; + GSList *handles_stale; gulong sig_id_1; gulong sig_id_2; @@ -122,14 +124,22 @@ upower_resuming_cb (GDBusProxy *proxy, gpointer user_data) #else /* USE_UPOWER */ static void -drop_inhibitor (NMSleepMonitor *self) +drop_inhibitor (NMSleepMonitor *self, gboolean force) { + if (!force && self->handles_active) + return; + if (self->inhibit_fd >= 0) { _LOGD ("inhibit: dropping sleep inhibitor %d", self->inhibit_fd); close (self->inhibit_fd); self->inhibit_fd = -1; } + if (self->handles_active) { + self->handles_stale = g_slist_concat (self->handles_stale, self->handles_active); + self->handles_active = NULL; + } + nm_clear_g_cancellable (&self->cancellable); } @@ -170,7 +180,7 @@ take_inhibitor (NMSleepMonitor *self) g_return_if_fail (NM_IS_SLEEP_MONITOR (self)); g_return_if_fail (G_IS_DBUS_PROXY (self->proxy)); - drop_inhibitor (self); + drop_inhibitor (self, TRUE); _LOGD ("inhibit: taking sleep inhibitor..."); self->cancellable = g_cancellable_new (); @@ -212,7 +222,7 @@ name_owner_cb (GObject *object, if (owner) take_inhibitor (self); else - drop_inhibitor (self); + drop_inhibitor (self, TRUE); g_free (owner); } #endif /* USE_UPOWER */ @@ -234,7 +244,57 @@ sleep_signal (NMSleepMonitor *self, #if !USE_UPOWER if (is_about_to_suspend) - drop_inhibitor (self); + drop_inhibitor (self, FALSE); +#endif +} + +/** + * nm_sleep_monitor_inhibit_take: + * @self: the #NMSleepMonitor instance + * + * Prevent the release of inhibitor lock + * + * Returns: an inhibitor handle that must be returned via + * nm_sleep_monitor_inhibit_release(). + **/ +NMSleepMonitorInhibitorHandle * +nm_sleep_monitor_inhibit_take (NMSleepMonitor *self) +{ + g_return_val_if_fail (NM_IS_SLEEP_MONITOR (self), NULL); + + self->handles_active = g_slist_prepend (self->handles_active, NULL); + return (NMSleepMonitorInhibitorHandle *) self->handles_active; +} + +/** + * nm_sleep_monitor_inhibit_release: + * @self: the #NMSleepMonitor instance + * @handle: the #NMSleepMonitorInhibitorHandle inhibitor handle. + * + * Allow again the release of inhibitor lock + **/ +void +nm_sleep_monitor_inhibit_release (NMSleepMonitor *self, + NMSleepMonitorInhibitorHandle *handle) +{ + GSList *l; + + g_return_if_fail (NM_IS_SLEEP_MONITOR (self)); + g_return_if_fail (handle); + + l = (GSList *) handle; + + if (g_slist_position (self->handles_active, l) < 0) { + if (g_slist_position (self->handles_stale, l) < 0) + g_return_if_reached (); + self->handles_stale = g_slist_delete_link (self->handles_stale, l); + return; + } + + self->handles_active = g_slist_delete_link (self->handles_active, l); + +#if !USE_UPOWER + drop_inhibitor (self, FALSE); #endif } @@ -303,7 +363,7 @@ dispose (GObject *object) NMSleepMonitor *self = NM_SLEEP_MONITOR (object); #if !USE_UPOWER - drop_inhibitor (self); + drop_inhibitor (self, TRUE); #endif nm_clear_g_cancellable (&self->cancellable); diff --git a/src/nm-sleep-monitor.h b/src/nm-sleep-monitor.h index 494a188eae..140f964f06 100644 --- a/src/nm-sleep-monitor.h +++ b/src/nm-sleep-monitor.h @@ -36,6 +36,12 @@ typedef struct _NMSleepMonitorClass NMSleepMonitorClass; GType nm_sleep_monitor_get_type (void) G_GNUC_CONST; NMSleepMonitor *nm_sleep_monitor_new (void); +typedef struct _NMSleepMonitorInhibitorHandle NMSleepMonitorInhibitorHandle; + +NMSleepMonitorInhibitorHandle *nm_sleep_monitor_inhibit_take (NMSleepMonitor *self); +void nm_sleep_monitor_inhibit_release (NMSleepMonitor *self, + NMSleepMonitorInhibitorHandle *handle); + G_END_DECLS #endif /* __NETWORKMANAGER_SLEEP_MONITOR_H__ */ |