diff options
author | Colin Walters <walters@verbum.org> | 2010-01-28 15:04:14 -0500 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2010-01-28 17:01:24 -0500 |
commit | b93476ce07acce83ff3b396616bb8a0eaf719916 (patch) | |
tree | 3e23a48387006d4cfcd16f49523c537f9b8c4759 /bus | |
parent | 0a3905d7f3b2ff43b09479863775939f9c8acad4 (diff) | |
download | dbus-b93476ce07acce83ff3b396616bb8a0eaf719916.tar.gz |
Don't drop pending activations when reloading configuration
The reload handling for activation simply dropped all knowledge
of pending activations, which was clearly wrong. Refactor things
so that reload only reloads directories, server address etc.
Based on a patch originally from Matthias Clasen <mclasen@redhat.com>
Diffstat (limited to 'bus')
-rw-r--r-- | bus/activation.c | 104 | ||||
-rw-r--r-- | bus/activation.h | 4 | ||||
-rw-r--r-- | bus/bus.c | 21 |
3 files changed, 80 insertions, 49 deletions
diff --git a/bus/activation.c b/bus/activation.c index 00caac27..0a28df16 100644 --- a/bus/activation.c +++ b/bus/activation.c @@ -735,74 +735,56 @@ out: return retval; } -BusActivation* -bus_activation_new (BusContext *context, - const DBusString *address, - DBusList **directories, - DBusError *error) +dbus_bool_t +bus_activation_reload (BusActivation *activation, + const DBusString *address, + DBusList **directories, + DBusError *error) { - BusActivation *activation; DBusList *link; char *dir; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - activation = dbus_new0 (BusActivation, 1); - if (activation == NULL) - { - BUS_SET_OOM (error); - return NULL; - } - - activation->refcount = 1; - activation->context = context; - activation->n_pending_activations = 0; - + + if (activation->server_address != NULL) + dbus_free (activation->server_address); if (!_dbus_string_copy_data (address, &activation->server_address)) { BUS_SET_OOM (error); goto failed; } - + + if (activation->entries != NULL) + _dbus_hash_table_unref (activation->entries); activation->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, (DBusFreeFunction)bus_activation_entry_unref); if (activation->entries == NULL) - { - BUS_SET_OOM (error); - goto failed; - } - - activation->pending_activations = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, - (DBusFreeFunction)bus_pending_activation_unref); - - if (activation->pending_activations == NULL) { BUS_SET_OOM (error); goto failed; } + if (activation->directories != NULL) + _dbus_hash_table_unref (activation->directories); activation->directories = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, (DBusFreeFunction)bus_service_directory_unref); - - if (activation->directories == NULL) + + if (activation->directories == NULL) { BUS_SET_OOM (error); goto failed; } - - /* Load service files */ + link = _dbus_list_get_first_link (directories); while (link != NULL) { BusServiceDirectory *s_dir; - + dir = _dbus_strdup ((const char *) link->data); if (!dir) { BUS_SET_OOM (error); goto failed; } - + s_dir = dbus_new0 (BusServiceDirectory, 1); if (!s_dir) { @@ -813,7 +795,7 @@ bus_activation_new (BusContext *context, s_dir->refcount = 1; s_dir->dir_c = dir; - + s_dir->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, (DBusFreeFunction)bus_activation_entry_unref); @@ -833,8 +815,8 @@ bus_activation_new (BusContext *context, /* only fail on OOM, it is ok if we can't read the directory */ if (!update_directory (activation, s_dir, error)) - { - if (dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY)) + { + if (dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY)) goto failed; else dbus_error_free (error); @@ -843,10 +825,52 @@ bus_activation_new (BusContext *context, link = _dbus_list_get_next_link (directories, link); } + return TRUE; + failed: + return FALSE; +} + +BusActivation* +bus_activation_new (BusContext *context, + const DBusString *address, + DBusList **directories, + DBusError *error) +{ + BusActivation *activation; + DBusList *link; + char *dir; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + activation = dbus_new0 (BusActivation, 1); + if (activation == NULL) + { + BUS_SET_OOM (error); + return NULL; + } + + activation->refcount = 1; + activation->context = context; + activation->n_pending_activations = 0; + + if (!bus_activation_reload (activation, address, directories, error)) + goto failed; + + /* Initialize this hash table once, we don't want to lose pending + * activations on reload. */ + activation->pending_activations = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, + (DBusFreeFunction)bus_pending_activation_unref); + + if (activation->pending_activations == NULL) + { + BUS_SET_OOM (error); + goto failed; + } + activation->environment = _dbus_hash_table_new (DBUS_HASH_STRING, (DBusFreeFunction) dbus_free, (DBusFreeFunction) dbus_free); - + if (activation->environment == NULL) { BUS_SET_OOM (error); diff --git a/bus/activation.h b/bus/activation.h index 2dff812a..03bfed28 100644 --- a/bus/activation.h +++ b/bus/activation.h @@ -32,6 +32,10 @@ BusActivation* bus_activation_new (BusContext *context, const DBusString *address, DBusList **directories, DBusError *error); +dbus_bool_t bus_activation_reload (BusActivation *activation, + const DBusString *address, + DBusList **directories, + DBusError *error); BusActivation* bus_activation_ref (BusActivation *activation); void bus_activation_unref (BusActivation *activation); @@ -498,21 +498,24 @@ process_config_every_time (BusContext *context, dbus_free(context->servicehelper); context->servicehelper = s; } - + /* Create activation subsystem */ - new_activation = bus_activation_new (context, &full_address, - dirs, error); - if (new_activation == NULL) + if (context->activation) + { + if (!bus_activation_reload (context->activation, &full_address, dirs, error)) + goto failed; + } + else + { + context->activation = bus_activation_new (context, &full_address, dirs, error); + } + + if (context->activation == NULL) { _DBUS_ASSERT_ERROR_IS_SET (error); goto failed; } - if (is_reload) - bus_activation_unref (context->activation); - - context->activation = new_activation; - /* Drop existing conf-dir watches (if applicable) */ if (is_reload) |