[evolution-data-server] EDBusServer: Add a use count, like in GApplication.



commit a7b7ae99a1eb6b820f978588626da772eb4cb4c0
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed Sep 28 18:39:17 2011 -0400

    EDBusServer: Add a use count, like in GApplication.
    
    Borrowing GApplication's use count concept for EDBusServer.  It works
    somewhat like a reference count: when the use count drops to zero, the
    main loop terminates (in this case, after a 10 second delay).  The use
    count usually follows the number of client connections.
    
    New functions to increment and decrement the use count:
    
        void e_dbus_server_hold    (EDBusServer *server)
        void e_dbus_server_release (EDBusServer *server)
    
    This lets us handle the --keep-running option more gracefully by
    simply incrementing the server's use count directly in main().
    
    For the record: I hemmed and hawed over a good while over whether to
    make EDBusServer inherit from GApplication or just copy the use count
    feature from GApplication.  In the end, I still think GApplication is
    over-engineered and tries to serve too many different use cases, so
    for now I'd prefer to keep EDBusServer simple.  I expect to revisit
    this decision at some point down the road.

 addressbook/libedata-book/e-data-book-factory.c    |   21 ++----
 calendar/libedata-cal/e-data-cal-factory.c         |   21 ++----
 .../reference/libebackend/libebackend-sections.txt |    2 +
 docs/reference/libebackend/tmpl/e-dbus-server.sgml |   16 ++++
 libebackend/e-dbus-server.c                        |   76 +++++++++++++++++++-
 libebackend/e-dbus-server.h                        |    2 +
 6 files changed, 109 insertions(+), 29 deletions(-)
---
diff --git a/addressbook/libedata-book/e-data-book-factory.c b/addressbook/libedata-book/e-data-book-factory.c
index 22853e3..d85d2db 100644
--- a/addressbook/libedata-book/e-data-book-factory.c
+++ b/addressbook/libedata-book/e-data-book-factory.c
@@ -96,8 +96,6 @@ struct _EDataBookFactoryPrivate {
 	/* This is a hash of client addresses to GList* of EDataBooks */
 	GHashTable *connections;
 
-	guint exit_timeout;
-
 #ifdef HAVE_GOA
 	GoaClient *goa_client;
 	GHashTable *goa_accounts;
@@ -194,13 +192,7 @@ book_freed_cb (EDataBookFactory *factory,
 		}
 	}
 
-	if (g_hash_table_size (priv->books) > 0)
-		return;
-
-	/* If there are no open books, start a timer to quit */
-	if (!opt_keep_running && priv->exit_timeout == 0)
-		priv->exit_timeout = g_timeout_add_seconds (
-			10, (GSourceFunc) e_dbus_server_quit, factory);
+	e_dbus_server_release (E_DBUS_SERVER (factory));
 }
 
 static gboolean
@@ -280,11 +272,7 @@ impl_BookFactory_get_book (EGdbusBookFactory *object,
 
 	g_mutex_lock (priv->books_lock);
 
-	/* Remove a pending exit */
-	if (priv->exit_timeout) {
-		g_source_remove (priv->exit_timeout);
-		priv->exit_timeout = 0;
-	}
+	e_dbus_server_hold (E_DBUS_SERVER (factory));
 
 #ifdef HAVE_GOA
 	{
@@ -643,6 +631,11 @@ main (gint argc,
 
 	g_print ("Server is up and running...\n");
 
+	/* This SHOULD keep the server's use
+	 * count from ever reaching zero. */
+	if (opt_keep_running)
+		e_dbus_server_hold (server);
+
 	e_dbus_server_run (server);
 
 	g_object_unref (server);
diff --git a/calendar/libedata-cal/e-data-cal-factory.c b/calendar/libedata-cal/e-data-cal-factory.c
index 806c348..31aef28 100644
--- a/calendar/libedata-cal/e-data-cal-factory.c
+++ b/calendar/libedata-cal/e-data-cal-factory.c
@@ -90,8 +90,6 @@ struct _EDataCalFactoryPrivate {
 	GMutex *connections_lock;
 	/* This is a hash of client addresses to GList* of EDataCals */
 	GHashTable *connections;
-
-	guint exit_timeout;
 };
 
 /* Forward Declarations */
@@ -207,13 +205,7 @@ calendar_freed_cb (EDataCalFactory *factory,
 		}
 	}
 
-	if (g_hash_table_size (priv->calendars) > 0)
-		return;
-
-	/* If there are no open calendars, start a timer to quit. */
-	if (!opt_keep_running && priv->exit_timeout == 0)
-		priv->exit_timeout = g_timeout_add_seconds (
-			10, (GSourceFunc) e_dbus_server_quit, factory);
+	e_dbus_server_release (E_DBUS_SERVER (factory));
 }
 
 static gboolean
@@ -292,11 +284,7 @@ impl_CalFactory_get_cal (EGdbusCalFactory *object,
 
 	g_mutex_lock (priv->calendars_lock);
 
-	/* Remove a pending exit */
-	if (priv->exit_timeout) {
-		g_source_remove (priv->exit_timeout);
-		priv->exit_timeout = 0;
-	}
+	e_dbus_server_hold (E_DBUS_SERVER (factory));
 
 	path = construct_cal_factory_path ();
 	calendar = e_data_cal_new (E_CAL_BACKEND (backend));
@@ -562,6 +550,11 @@ main (gint argc,
 
 	g_print ("Server is up and running...\n");
 
+	/* This SHOULD keep the server's use
+	 * count from ever reaching zero. */
+	if (opt_keep_running)
+		e_dbus_server_hold (server);
+
 	e_dbus_server_run (server);
 
 	g_object_unref (server);
diff --git a/docs/reference/libebackend/libebackend-sections.txt b/docs/reference/libebackend/libebackend-sections.txt
index 6e401dd..c54cdbc 100644
--- a/docs/reference/libebackend/libebackend-sections.txt
+++ b/docs/reference/libebackend/libebackend-sections.txt
@@ -63,6 +63,8 @@ e_data_factory_get_type
 EDBusServer
 e_dbus_server_run
 e_dbus_server_quit
+e_dbus_server_hold
+e_dbus_server_release
 e_dbus_server_load_modules
 <SUBSECTION Standard>
 E_DBUS_SERVER
diff --git a/docs/reference/libebackend/tmpl/e-dbus-server.sgml b/docs/reference/libebackend/tmpl/e-dbus-server.sgml
index 1aaf4c3..b850551 100644
--- a/docs/reference/libebackend/tmpl/e-dbus-server.sgml
+++ b/docs/reference/libebackend/tmpl/e-dbus-server.sgml
@@ -66,6 +66,22 @@ EDBusServer
 @server: 
 
 
+<!-- ##### FUNCTION e_dbus_server_hold ##### -->
+<para>
+
+</para>
+
+ server: 
+
+
+<!-- ##### FUNCTION e_dbus_server_release ##### -->
+<para>
+
+</para>
+
+ server: 
+
+
 <!-- ##### FUNCTION e_dbus_server_load_modules ##### -->
 <para>
 
diff --git a/libebackend/e-dbus-server.c b/libebackend/e-dbus-server.c
index 367b4cf..194ecbf 100644
--- a/libebackend/e-dbus-server.c
+++ b/libebackend/e-dbus-server.c
@@ -37,10 +37,15 @@
 	(G_TYPE_INSTANCE_GET_PRIVATE \
 	((obj), E_TYPE_DBUS_SERVER, EDBusServerPrivate))
 
+#define INACTIVITY_TIMEOUT 10  /* seconds */
+
 struct _EDBusServerPrivate {
 	GMainLoop *main_loop;
 	guint bus_owner_id;
 	guint terminate_id;
+
+	guint inactivity_timeout_id;
+	guint use_count;
 };
 
 enum {
@@ -80,6 +85,14 @@ dbus_server_name_lost_cb (GDBusConnection *connection,
 	g_signal_emit (server, signals[BUS_NAME_LOST], 0, connection);
 }
 
+static gboolean
+dbus_server_inactivity_timeout_cb (EDBusServer *server)
+{
+	e_dbus_server_quit (server);
+
+	return FALSE;
+}
+
 #ifdef G_OS_UNIX
 static gboolean
 dbus_server_terminate_cb (EDBusServer *server)
@@ -104,6 +117,9 @@ dbus_server_finalize (GObject *object)
 	if (priv->terminate_id > 0)
 		g_source_remove (priv->terminate_id);
 
+	if (priv->inactivity_timeout_id > 0)
+		g_source_remove (priv->inactivity_timeout_id);
+
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (e_dbus_server_parent_class)->finalize (object);
 }
@@ -112,7 +128,12 @@ static void
 dbus_server_bus_acquired (EDBusServer *server,
                           GDBusConnection *connection)
 {
-	/* Placeholder so subclasses can safely chain up. */
+	if (server->priv->use_count == 0)
+		server->priv->inactivity_timeout_id =
+			g_timeout_add_seconds (
+				INACTIVITY_TIMEOUT, (GSourceFunc)
+				dbus_server_inactivity_timeout_cb,
+				server);
 }
 
 static void
@@ -235,6 +256,59 @@ e_dbus_server_quit (EDBusServer *server)
 	g_main_loop_quit (server->priv->main_loop);
 }
 
+/**
+ * e_dbus_server_hold:
+ * @server: an #EDBusServer
+ *
+ * Increases the use count of @server.
+ *
+ * Use this function to indicate that the server has a reason to continue
+ * to run.  To cancel the hold, call e_dbus_server_release().
+ *
+ * Since: 3.4
+ **/
+void
+e_dbus_server_hold (EDBusServer *server)
+{
+	g_return_if_fail (E_IS_DBUS_SERVER (server));
+
+	if (server->priv->inactivity_timeout_id > 0) {
+		g_source_remove (server->priv->inactivity_timeout_id);
+		server->priv->inactivity_timeout_id = 0;
+	}
+
+	server->priv->use_count++;
+}
+
+/**
+ * e_dbus_server_release:
+ * @server: an #EDBusServer
+ *
+ * Decreates the use count of @server.
+ *
+ * When the use count reaches zero, the server will stop running.
+ *
+ * Never call this function except to cancel the effect of a previous call
+ * to e_dbus_server_hold().
+ *
+ * Since: 3.4
+ **/
+void
+e_dbus_server_release (EDBusServer *server)
+{
+	g_return_if_fail (E_IS_DBUS_SERVER (server));
+	g_return_if_fail (server->priv->use_count > 0);
+
+	server->priv->use_count--;
+
+	if (server->priv->use_count == 0)
+		server->priv->inactivity_timeout_id =
+			g_timeout_add_seconds (
+				INACTIVITY_TIMEOUT, (GSourceFunc)
+				dbus_server_inactivity_timeout_cb,
+				server);
+}
+
 void
 e_dbus_server_load_modules (EDBusServer *server)
 {
diff --git a/libebackend/e-dbus-server.h b/libebackend/e-dbus-server.h
index 82d8c6f..19af800 100644
--- a/libebackend/e-dbus-server.h
+++ b/libebackend/e-dbus-server.h
@@ -79,6 +79,8 @@ struct _EDBusServerClass {
 GType		e_dbus_server_get_type		(void) G_GNUC_CONST;
 void		e_dbus_server_run		(EDBusServer *server);
 void		e_dbus_server_quit		(EDBusServer *server);
+void		e_dbus_server_hold		(EDBusServer *server);
+void		e_dbus_server_release		(EDBusServer *server);
 void		e_dbus_server_load_modules	(EDBusServer *server);
 
 G_END_DECLS



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