From b0f2060628caa2fbbf7a31bddd418623808508a7 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 3 Nov 2008 15:00:31 +0000 Subject: [PATCH] Exit when no devices are in use When no actions are happening on any of the devices, make the daemon exit after 30 seconds. --- src/fprintd.h | 2 ++ src/main.c | 2 ++ src/manager.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/src/fprintd.h b/src/fprintd.h index 7bb3db6..bed50b6 100644 --- a/src/fprintd.h +++ b/src/fprintd.h @@ -24,8 +24,10 @@ #include /* General */ +#define TIMEOUT 30 #define FPRINT_SERVICE_NAME "net.reactivated.Fprint" extern DBusGConnection *fprintd_dbus_conn; +extern gboolean no_timeout; GQuark fprint_error_quark(void); /* Errors */ diff --git a/src/main.c b/src/main.c index 2a6bd61..e7c29be 100644 --- a/src/main.c +++ b/src/main.c @@ -34,6 +34,7 @@ #include "file_storage.h" DBusGConnection *fprintd_dbus_conn = NULL; +gboolean no_timeout = FALSE; static gboolean g_fatal_warnings = FALSE; GQuark fprint_error_quark(void) @@ -287,6 +288,7 @@ bail: static const GOptionEntry entries[] = { {"g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL}, + {"no-timeout", 't', 0, G_OPTION_ARG_NONE, &no_timeout, "Do not exit after unused for a while", NULL}, { NULL } }; diff --git a/src/manager.c b/src/manager.c index f39729e..158c362 100644 --- a/src/manager.c +++ b/src/manager.c @@ -17,6 +17,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include +#include #include #include #include @@ -38,6 +40,8 @@ typedef struct { GError *last_error; GSList *dev_registry; + guint timeout_id; + volatile int num_device_used; } FprintManagerPrivate; #define FPRINT_MANAGER_GET_PRIVATE(o) \ @@ -71,6 +75,35 @@ static gchar *get_device_path(FprintDevice *rdev) _fprint_device_get_id(rdev)); } +static gboolean +fprint_manager_timeout_cb (FprintManager *manager) +{ + g_message ("No devices in use, exit"); + //FIXME kill all the devices + exit(0); +} + +static void +fprint_manager_action_notified (FprintDevice *rdev, GParamSpec *spec, FprintManager *manager) +{ + FprintManagerPrivate *priv = FPRINT_MANAGER_GET_PRIVATE (manager); + int action; + + g_object_get (G_OBJECT(rdev), "action", &action, NULL); + if (priv->timeout_id > 0) { + g_source_remove (priv->timeout_id); + priv->timeout_id = 0; + } + if (action == 0) { + if (g_atomic_int_dec_and_test (&priv->num_device_used)) { + if (!no_timeout) + priv->timeout_id = g_timeout_add_seconds (TIMEOUT, (GSourceFunc) fprint_manager_timeout_cb, manager); + } + } else { + g_atomic_int_add (&priv->num_device_used, 1); + } +} + static void fprint_manager_init (FprintManager *manager) { @@ -79,6 +112,8 @@ fprint_manager_init (FprintManager *manager) struct fp_dscv_dev *ddev; int i = 0; + priv->num_device_used = 0; + if (!discovered_devs) { priv->last_error = g_error_new (FPRINT_ERROR, FPRINT_ERROR_INTERNAL, _("An internal error occurred in libfprint")); @@ -92,12 +127,18 @@ fprint_manager_init (FprintManager *manager) FprintDevice *rdev = fprint_device_new(ddev); gchar *path; + g_signal_connect (G_OBJECT(rdev), "notify::action", + G_CALLBACK (fprint_manager_action_notified), manager); + priv->dev_registry = g_slist_prepend(priv->dev_registry, rdev); path = get_device_path(rdev); dbus_g_connection_register_g_object(fprintd_dbus_conn, path, G_OBJECT(rdev)); g_free(path); } + + if (!no_timeout) + priv->timeout_id = g_timeout_add_seconds (TIMEOUT, (GSourceFunc) fprint_manager_timeout_cb, manager); } FprintManager *fprint_manager_new(void)