summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@src.gnome.org>2003-03-13 12:55:41 +0000
committerAnders Carlsson <andersca@src.gnome.org>2003-03-13 12:55:41 +0000
commit89adfbc77d3124634a98e9bad5a44d8e6fae2348 (patch)
tree4defc7392dc5fc1b0b79cea42a834aa63a82f4be
parentd86cffdc5d03c4f45fb091c88e5928c063530574 (diff)
downloadgconf-89adfbc77d3124634a98e9bad5a44d8e6fae2348.tar.gz
Handle client lifecycle
-rw-r--r--gconf/gconf-database-corba.c3
-rw-r--r--gconf/gconfd-dbus.c143
-rw-r--r--gconf/gconfd-dbus.h3
-rw-r--r--gconf/gconfd.c3
4 files changed, 141 insertions, 11 deletions
diff --git a/gconf/gconf-database-corba.c b/gconf/gconf-database-corba.c
index 03f8ab8b..50f0feb5 100644
--- a/gconf/gconf-database-corba.c
+++ b/gconf/gconf-database-corba.c
@@ -1061,6 +1061,9 @@ client_alive_predicate (const gchar* location,
Listener *l = listener_data;
CORBA_Environment ev;
CORBA_boolean result;
+
+ if (l->parent.type != GCONF_DATABASE_LISTENER_CORBA)
+ return TRUE;
CORBA_exception_init (&ev);
diff --git a/gconf/gconfd-dbus.c b/gconf/gconfd-dbus.c
index edc34ba2..50092662 100644
--- a/gconf/gconfd-dbus.c
+++ b/gconf/gconfd-dbus.c
@@ -23,9 +23,14 @@
#include "gconfd.h"
#include "gconf-dbus.h"
#include <time.h>
+#include <string.h>
+
+static const char *config_server_messages[] = {
+ GCONF_DBUS_CONFIG_SERVER_SHUTDOWN,
+};
static const char *config_database_messages[] = {
- GCONF_DBUS_CONFIG_DATABASE_DIR_EXISTS,
+ GCONF_DBUS_CONFIG_DATABASE_DIR_EXISTS,
GCONF_DBUS_CONFIG_DATABASE_ALL_DIRS,
GCONF_DBUS_CONFIG_DATABASE_ALL_ENTRIES,
GCONF_DBUS_CONFIG_DATABASE_LOOKUP,
@@ -41,9 +46,8 @@ static const char *config_database_messages[] = {
GCONF_DBUS_CONFIG_DATABASE_CLEAR_CACHE
};
-static const char *config_server_messages[] =
-{
- GCONF_DBUS_CONFIG_SERVER_SHUTDOWN
+static const char *lifecycle_messages[] = {
+ DBUS_MESSAGE_SERVICE_DELETED,
};
typedef struct {
@@ -54,6 +58,8 @@ typedef struct {
static Listener* listener_new (const char *who,
const char *name);
static void listener_destroy (Listener *l);
+static void add_client (DBusConnection *connection,
+ const char *name);
static void
gconfd_shutdown (DBusConnection *connection,
@@ -650,11 +656,9 @@ static void
gconfd_config_database_unset (DBusConnection *connection,
DBusMessage *message)
{
- guint flags;
int id;
gchar *key;
GConfDatabase *db;
- GConfUnsetFlags gconf_flags;
DBusMessage *reply;
GError *error = NULL;
@@ -728,7 +732,6 @@ static void
gconfd_config_database_synchronous_sync (DBusConnection *connection,
DBusMessage *message)
{
- guint flags;
int id;
GConfDatabase *db;
DBusMessage *reply;
@@ -761,7 +764,6 @@ static void
gconfd_config_database_sync (DBusConnection *connection,
DBusMessage *message)
{
- guint flags;
int id;
GConfDatabase *db;
DBusMessage *reply;
@@ -823,6 +825,112 @@ gconfd_config_database_clear_cache (DBusConnection *connection,
dbus_message_unref (reply);
}
+static GHashTable *client_hash = NULL;
+
+static void
+add_client (DBusConnection *connection,
+ const char *name)
+{
+ char *tmp;
+
+ if (!client_hash)
+ client_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ /* Check if client is in the hash already */
+ if (g_hash_table_lookup (client_hash, name))
+ return;
+
+ tmp = g_strdup (name);
+ g_hash_table_insert (client_hash, tmp, tmp);
+
+ gconf_log (GCL_DEBUG, "Added a new client");
+}
+
+guint
+gconfd_dbus_client_count (void)
+{
+ return g_hash_table_size (client_hash);
+}
+
+static gboolean
+remove_listener_predicate (const gchar* location,
+ guint cnxn_id,
+ gpointer listener_data,
+ gpointer user_data)
+{
+ Listener *l = listener_data;
+ const char *name = user_data;
+
+ if (l->parent.type != GCONF_DATABASE_LISTENER_DBUS)
+ return TRUE;
+
+ if (strcmp (l->who, name) == 0)
+ {
+ printf ("removing listener!\n");
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+static void
+remove_listeners (GConfDatabase *db, const char *name)
+{
+ if (db->listeners)
+ {
+ gconf_listeners_remove_if (db->listeners,
+ remove_listener_predicate,
+ (gpointer)name);
+ }
+}
+
+static void
+remove_client (DBusConnection *connection,
+ DBusMessage *message)
+{
+ char *name;
+ GList *list;
+ GConfDatabase *db;
+
+ dbus_message_get_args (message,
+ DBUS_TYPE_STRING, &name,
+ 0);
+
+ /* Check if we know the client */
+ if (g_hash_table_lookup (client_hash, name) == NULL)
+ {
+ dbus_free (name);
+ return;
+ }
+
+ /* Now clean up after it */
+ list = gconfd_get_database_list ();
+ while (list)
+ {
+ db = list->data;
+ remove_listeners (db, name);
+ list = list->next;
+ }
+
+ /* Clean up the default database */
+ db = gconfd_lookup_database (NULL);
+ remove_listeners (db, name);
+ g_hash_table_remove (client_hash, name);
+ dbus_free (name);
+}
+
+static DBusHandlerResult
+gconfd_lifecycle_handler (DBusMessageHandler *handler,
+ DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ if (dbus_message_name_is (message, DBUS_MESSAGE_SERVICE_DELETED))
+ remove_client (connection, message);
+
+ return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+}
+
static DBusHandlerResult
gconfd_config_database_handler (DBusMessageHandler *handler,
DBusConnection *connection,
@@ -831,71 +939,85 @@ gconfd_config_database_handler (DBusMessageHandler *handler,
{
if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_DIR_EXISTS))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_dir_exists (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
else if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_ALL_DIRS))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_all_dirs (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
else if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_ALL_ENTRIES))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_all_entries (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
else if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_LOOKUP))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_lookup (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
else if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_LOOKUP_DEFAULT_VALUE))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_lookup_default_value (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
else if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_REMOVE_DIR))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_remove_dir (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
else if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_ADD_LISTENER))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_add_listener (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
else if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_SET))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_set (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
else if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_RECURSIVE_UNSET))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_recursive_unset (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
else if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_UNSET))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_unset (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
else if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_SET_SCHEMA))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_set_schema (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
else if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_SYNC))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_sync (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
else if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_SYNCHRONOUS_SYNC))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_synchronous_sync (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
else if (dbus_message_name_is (message, GCONF_DBUS_CONFIG_DATABASE_CLEAR_CACHE))
{
+ add_client (connection, dbus_message_get_sender (message));
gconfd_config_database_clear_cache (connection, message);
return DBUS_HANDLER_RESULT_REMOVE_MESSAGE;
}
@@ -964,6 +1086,11 @@ gconfd_dbus_init (void)
handler = dbus_message_handler_new (gconfd_config_database_handler, NULL, NULL);
dbus_connection_register_handler (dbus_conn, handler, config_database_messages,
G_N_ELEMENTS (config_database_messages));
+
+ /* Add the lifecycle handler */
+ handler = dbus_message_handler_new (gconfd_lifecycle_handler, NULL, NULL);
+ dbus_connection_register_handler (dbus_conn, handler, lifecycle_messages,
+ G_N_ELEMENTS (lifecycle_messages));
return TRUE;
}
diff --git a/gconf/gconfd-dbus.h b/gconf/gconfd-dbus.h
index 7d5bb0f1..c2df882e 100644
--- a/gconf/gconfd-dbus.h
+++ b/gconf/gconfd-dbus.h
@@ -26,7 +26,7 @@
gboolean gconfd_dbus_init (void);
gboolean gconfd_dbus_check_in_shutdown (DBusConnection *connection,
DBusMessage *message);
-
+guint gconfd_dbus_client_count (void);
void gconf_database_dbus_notify_listeners (GConfDatabase *db,
const gchar *key,
const GConfValue *value,
@@ -34,5 +34,4 @@ void gconf_database_dbus_notify_listeners (GConfDatabase *db,
gboolean is_writable);
-
#endif
diff --git a/gconf/gconfd.c b/gconf/gconfd.c
index 4c8fc2a3..9438c017 100644
--- a/gconf/gconfd.c
+++ b/gconf/gconfd.c
@@ -533,7 +533,8 @@ periodic_cleanup_timeout(gpointer data)
gconfd_corba_drop_old_clients ();
drop_old_databases ();
- if (no_databases_in_use () && gconfd_corba_client_count () == 0)
+ if (no_databases_in_use () && gconfd_corba_client_count () == 0 &&
+ gconfd_dbus_client_count () == 0)
{
gconf_log (GCL_INFO, _("GConf server is not in use, shutting down."));
gconf_main_quit ();