[gcr] gcr: Add timeout to gcr-prompter process



commit f8d85a9bfd74bc75b29a41f952c221c0d610ffe1
Author: Stef Walter <stefw collabora co uk>
Date:   Sun Dec 18 19:54:51 2011 +0100

    gcr: Add timeout to gcr-prompter process
    
     * When no prompts occur for 10 seconds, quit process

 docs/reference/gcr/gcr-sections.txt |    1 +
 gcr/Makefile.am                     |    3 +-
 gcr/gcr-base.symbols                |    1 +
 gcr/gcr-prompter-tool.c             |  114 ++++++++++++++++++++++++++++++++---
 gcr/gcr-system-prompter.c           |   42 ++++++++++++-
 gcr/gcr-system-prompter.h           |    6 +-
 6 files changed, 150 insertions(+), 17 deletions(-)
---
diff --git a/docs/reference/gcr/gcr-sections.txt b/docs/reference/gcr/gcr-sections.txt
index 4b90f39..f9b3e02 100644
--- a/docs/reference/gcr/gcr-sections.txt
+++ b/docs/reference/gcr/gcr-sections.txt
@@ -802,6 +802,7 @@ gcr_system_prompter_register
 gcr_system_prompter_unregister
 gcr_system_prompter_get_mode
 gcr_system_prompter_get_prompt_type
+gcr_system_prompter_get_prompting
 <SUBSECTION Private>
 GcrSystemPrompterPrivate
 gcr_system_prompter_get_type
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index 8e3b63b..f1d1bba 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -341,7 +341,8 @@ gcr_viewer_LDADD = \
 libexec_PROGRAMS = gcr-prompter
 
 gcr_prompter_SOURCES = \
-	gcr-prompter-tool.c
+	gcr-prompter-tool.c \
+	gcr-debug.c gcr-debug.h
 
 gcr_prompter_CFLAGS = \
 	$(GTK_CFLAGS)
diff --git a/gcr/gcr-base.symbols b/gcr/gcr-base.symbols
index b77f10d..5ca9cbd 100644
--- a/gcr/gcr-base.symbols
+++ b/gcr/gcr-base.symbols
@@ -196,6 +196,7 @@ gcr_simple_collection_new
 gcr_simple_collection_remove
 gcr_system_prompter_get_mode
 gcr_system_prompter_get_prompt_type
+gcr_system_prompter_get_prompting
 gcr_system_prompter_get_type
 gcr_system_prompter_mode_get_type
 gcr_system_prompter_new
diff --git a/gcr/gcr-prompter-tool.c b/gcr/gcr-prompter-tool.c
index b897a0c..e888b41 100644
--- a/gcr/gcr-prompter-tool.c
+++ b/gcr/gcr-prompter-tool.c
@@ -37,6 +37,7 @@
 #include <locale.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
 
 #define QUIT_TIMEOUT 10
 
@@ -44,41 +45,56 @@ static GcrSystemPrompter *the_prompter = NULL;
 static gboolean registered_prompter = FALSE;
 static gboolean acquired_system_prompter = FALSE;
 static gboolean acquired_private_prompter = FALSE;
+static guint timeout_source = 0;
 
-#if 0
 static gboolean
 on_timeout_quit (gpointer unused)
 {
+	_gcr_debug ("%d second inactivity timeout, quitting", QUIT_TIMEOUT);
 	gtk_main_quit ();
+
 	return FALSE; /* Don't run again */
 }
 
 static void
-start_timeout (GcrPrompterDialog *self)
+start_timeout (void)
 {
 	if (g_getenv ("GCR_PERSIST") != NULL)
 		return;
 
-	if (!self->quit_timeout)
-		self->quit_timeout = g_timeout_add_seconds (QUIT_TIMEOUT, on_timeout_quit, NULL);
+	if (!timeout_source)
+		timeout_source = g_timeout_add_seconds (QUIT_TIMEOUT, on_timeout_quit, NULL);
 }
 
 static void
-stop_timeout (GcrPrompterDialog *self)
+stop_timeout (void)
 {
-	if (self->quit_timeout)
-		g_source_remove (self->quit_timeout);
-	self->quit_timeout = 0;
+	if (timeout_source)
+		g_source_remove (timeout_source);
+	timeout_source = 0;
+}
+
+static void
+on_prompter_prompting (GObject *obj,
+                       GParamSpec param,
+                       gpointer user_data)
+{
+	if (gcr_system_prompter_get_prompting (the_prompter))
+		stop_timeout ();
+	else
+		start_timeout ();
 }
-#endif
 
 static void
 on_bus_acquired (GDBusConnection *connection,
                  const gchar *name,
                  gpointer user_data)
 {
+	_gcr_debug ("bus acquired: %s", name);
+
 	if (!registered_prompter)
 		gcr_system_prompter_register (the_prompter, connection);
+
 	registered_prompter = TRUE;
 }
 
@@ -87,6 +103,8 @@ on_name_acquired (GDBusConnection *connection,
                   const gchar *name,
                   gpointer user_data)
 {
+	_gcr_debug ("acquired name: %s", name);
+
 	if (g_strcmp0 (name, GCR_DBUS_PROMPTER_SYSTEM_BUS_NAME) == 0)
 		acquired_system_prompter = TRUE;
 
@@ -99,6 +117,8 @@ on_name_lost (GDBusConnection *connection,
               const gchar *name,
               gpointer user_data)
 {
+	_gcr_debug ("lost name: %s", name);
+
 	/* Called like so when no connection can be made */
 	if (connection == NULL) {
 		g_warning ("couldn't connect to session bus");
@@ -113,6 +133,77 @@ on_name_lost (GDBusConnection *connection,
 	}
 }
 
+static void
+log_handler (const gchar *log_domain,
+             GLogLevelFlags log_level,
+             const gchar *message,
+             gpointer user_data)
+{
+	int level;
+
+	/* Note that crit and err are the other way around in syslog */
+
+	switch (G_LOG_LEVEL_MASK & log_level) {
+	case G_LOG_LEVEL_ERROR:
+		level = LOG_CRIT;
+		break;
+	case G_LOG_LEVEL_CRITICAL:
+		level = LOG_ERR;
+		break;
+	case G_LOG_LEVEL_WARNING:
+		level = LOG_WARNING;
+		break;
+	case G_LOG_LEVEL_MESSAGE:
+		level = LOG_NOTICE;
+		break;
+	case G_LOG_LEVEL_INFO:
+		level = LOG_INFO;
+		break;
+	case G_LOG_LEVEL_DEBUG:
+		level = LOG_DEBUG;
+		break;
+	default:
+		level = LOG_ERR;
+		break;
+	}
+
+	/* Log to syslog first */
+	if (log_domain)
+		syslog (level, "%s: %s", log_domain, message);
+	else
+		syslog (level, "%s", message);
+
+	/* And then to default handler for aborting and stuff like that */
+	g_log_default_handler (log_domain, log_level, message, user_data);
+}
+
+static void
+printerr_handler (const gchar *string)
+{
+	/* Print to syslog and stderr */
+	syslog (LOG_WARNING, "%s", string);
+	fprintf (stderr, "%s", string);
+}
+
+static void
+prepare_logging ()
+{
+	GLogLevelFlags flags = G_LOG_FLAG_FATAL | G_LOG_LEVEL_ERROR |
+	                       G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
+	                       G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO;
+
+	openlog ("gcr-prompter", LOG_PID, LOG_AUTH);
+
+	g_log_set_handler (NULL, flags, log_handler, NULL);
+	g_log_set_handler ("Glib", flags, log_handler, NULL);
+	g_log_set_handler ("Gtk", flags, log_handler, NULL);
+	g_log_set_handler ("Gnome", flags, log_handler, NULL);
+	g_log_set_handler ("Gcr", flags, log_handler, NULL);
+	g_log_set_handler ("Gck", flags, log_handler, NULL);
+	g_log_set_default_handler (log_handler, NULL);
+	g_set_printerr_handler (printerr_handler);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -133,8 +224,12 @@ main (int argc, char *argv[])
 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 #endif
 
+	prepare_logging ();
+
 	the_prompter = gcr_system_prompter_new (GCR_SYSTEM_PROMPTER_SINGLE,
 	                                        GCR_TYPE_PROMPT_DIALOG);
+	g_signal_connect (the_prompter, "notify::prompting",
+	                  G_CALLBACK (on_prompter_prompting), NULL);
 
 	system_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
 	                                  GCR_DBUS_PROMPTER_SYSTEM_BUS_NAME,
@@ -154,6 +249,7 @@ main (int argc, char *argv[])
 	                                   NULL,
 	                                   NULL);
 
+	start_timeout ();
 	gtk_main ();
 
 	if (registered_prompter)
diff --git a/gcr/gcr-system-prompter.c b/gcr/gcr-system-prompter.c
index 60b96c6..034b918 100644
--- a/gcr/gcr-system-prompter.c
+++ b/gcr/gcr-system-prompter.c
@@ -61,7 +61,6 @@
 
 /**
  * GcrSystemPrompterClass:
- * @parent_class: prompter class
  *
  * The class for #GcrSystemPrompter.
  */
@@ -78,7 +77,12 @@
 enum {
 	PROP_0,
 	PROP_MODE,
-	PROP_PROMPT_TYPE
+	PROP_PROMPT_TYPE,
+	PROP_PROMPTING
+};
+
+struct _GcrSystemPrompterClass {
+	GObjectClass parent_class;
 };
 
 struct _GcrSystemPrompterPrivate {
@@ -278,6 +282,9 @@ gcr_system_prompter_get_property (GObject *obj,
 	case PROP_PROMPT_TYPE:
 		g_value_set_gtype (value, gcr_system_prompter_get_prompt_type (self));
 		break;
+	case PROP_PROMPTING:
+		g_value_set_boolean (value, gcr_system_prompter_get_prompting (self));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
 		break;
@@ -296,6 +303,7 @@ gcr_system_prompter_dispose (GObject *obj)
 
 	g_hash_table_remove_all (self->pv->callbacks);
 	g_hash_table_remove_all (self->pv->active);
+	g_object_notify (obj, "prompting");
 
 	G_OBJECT_CLASS (gcr_system_prompter_parent_class)->dispose (obj);
 }
@@ -351,6 +359,16 @@ gcr_system_prompter_class_init (GcrSystemPrompterClass *klass)
 	             g_param_spec_gtype ("prompt-type", "Prompt GType", "GObject type of prompts",
 	                                 GCR_TYPE_PROMPT,
 	                                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+	/**
+	 * GcrSystemPrompter:prompting:
+	 *
+	 * Whether the prompter is prompting or not.
+	 */
+	g_object_class_install_property (gobject_class, PROP_PROMPTING,
+	           g_param_spec_boolean ("prompting", "Prompting", "Whether prompting or not",
+	                                 FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
 }
 
 static GVariantBuilder *
@@ -459,6 +477,7 @@ prompt_stop_prompting (GcrSystemPrompter *self,
 
 	/* And all traces gone, including watch */
 	g_hash_table_remove (self->pv->callbacks, callback);
+	g_object_notify (G_OBJECT (self), "prompting");
 }
 
 static void
@@ -489,8 +508,8 @@ on_prompt_ready_complete (GObject *source,
 		else
 			g_message ("received an error from the prompt callback: %s", error->message);
 		g_error_free (error);
+
 		prompt_stop_prompting (self, active->callback, FALSE, FALSE);
-		g_hash_table_remove (self->pv->callbacks, active->callback);
 
 		/* Another new prompt may be ready to go active? */
 		prompt_next_ready (self);
@@ -656,6 +675,8 @@ prompter_method_begin_prompting (GcrSystemPrompter *self,
 	g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
 
 	g_queue_push_tail (&self->pv->waiting, callback);
+	g_object_notify (G_OBJECT (self), "prompting");
+
 	prompt_next_ready (self);
 }
 
@@ -966,3 +987,18 @@ gcr_system_prompter_get_prompt_type (GcrSystemPrompter *self)
 	g_return_val_if_fail (GCR_IS_SYSTEM_PROMPTER (self), 0);
 	return self->pv->prompt_type;
 }
+
+/**
+ * gcr_system_prompter_get_prompting:
+ * @self: the prompter
+ *
+ * Get whether prompting or not.
+ *
+ * Returns: whether prompting or not
+ */
+gboolean
+gcr_system_prompter_get_prompting (GcrSystemPrompter *self)
+{
+	g_return_val_if_fail (GCR_IS_SYSTEM_PROMPTER (self), FALSE);
+	return g_hash_table_size (self->pv->callbacks);
+}
diff --git a/gcr/gcr-system-prompter.h b/gcr/gcr-system-prompter.h
index 57ae481..f6f04d3 100644
--- a/gcr/gcr-system-prompter.h
+++ b/gcr/gcr-system-prompter.h
@@ -58,10 +58,6 @@ struct _GcrSystemPrompter {
 	GcrSystemPrompterPrivate *pv;
 };
 
-struct _GcrSystemPrompterClass {
-	GObjectClass parent_class;
-};
-
 GType                  gcr_system_prompter_get_type                (void) G_GNUC_CONST;
 
 GcrSystemPrompter *    gcr_system_prompter_new                     (GcrSystemPrompterMode mode,
@@ -71,6 +67,8 @@ GcrSystemPrompterMode  gcr_system_prompter_get_mode                (GcrSystemPro
 
 GType                  gcr_system_prompter_get_prompt_type         (GcrSystemPrompter *self);
 
+gboolean               gcr_system_prompter_get_prompting           (GcrSystemPrompter *self);
+
 void                   gcr_system_prompter_register                (GcrSystemPrompter *self,
                                                                     GDBusConnection *connection);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]