summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikael Hallendal <micke@imendio.com>2004-03-12 14:15:14 +0000
committerMikael Hallendal <micke@imendio.com>2004-03-12 14:15:14 +0000
commit520bdf704d2ff845b9e4cb91c8262245767f340a (patch)
tree8f9e7ff0990670385fc55272fa4c927416ff4bb2
parentdd79fc73f08574698c18c6a35dc309d5ef33fde0 (diff)
2004-03-12 Mikael Hallendal <micke@imendio.com>
* bus/activation.c: (babysitter_watch_callback): notify all pending activations waiting for the same exec that the activation failed. (bus_activation_activate_service): shortcut the activation if we already waiting for the same executable to start up.
-rw-r--r--ChangeLog8
-rw-r--r--bus/activation.c64
2 files changed, 64 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 95950110..e3317afc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2004-03-12 Mikael Hallendal <micke@imendio.com>
+ * bus/activation.c:
+ (babysitter_watch_callback): notify all pending activations waiting for
+ the same exec that the activation failed.
+ (bus_activation_activate_service): shortcut the activation if we
+ already waiting for the same executable to start up.
+
+2004-03-12 Mikael Hallendal <micke@imendio.com>
+
* bus/activation.c:
- Added service file reloading.
Each service files directory is kept in an hash table in
diff --git a/bus/activation.c b/bus/activation.c
index 26b1e044..e53fa229 100644
--- a/bus/activation.c
+++ b/bus/activation.c
@@ -83,6 +83,7 @@ typedef struct
int refcount;
BusActivation *activation;
char *service_name;
+ char *exec;
DBusList *entries;
int n_entries;
DBusBabysitter *babysitter;
@@ -187,6 +188,7 @@ bus_pending_activation_unref (BusPendingActivation *pending_activation)
}
dbus_free (pending_activation->service_name);
+ dbus_free (pending_activation->exec);
link = _dbus_list_get_first_link (&pending_activation->entries);
@@ -1039,10 +1041,22 @@ babysitter_watch_callback (DBusWatch *watch,
if (_dbus_babysitter_get_child_exited (babysitter))
{
DBusError error;
-
+ DBusHashIter iter;
+
dbus_error_init (&error);
_dbus_babysitter_set_child_exit_error (babysitter, &error);
+ /* Destroy all pending activations with the same exec */
+ _dbus_hash_iter_init (pending_activation->activation->pending_activations,
+ &iter);
+ while (_dbus_hash_iter_next (&iter))
+ {
+ BusPendingActivation *p = _dbus_hash_iter_get_value (&iter);
+
+ if (p != pending_activation && strcmp (p->exec, pending_activation->exec) == 0)
+ pending_activation_failed (p, &error);
+ }
+
/* Destroys the pending activation */
pending_activation_failed (pending_activation, &error);
@@ -1085,7 +1099,8 @@ pending_activation_timed_out (void *data)
* (not sure this is what we want to do, but
* may as well try it for now)
*/
- _dbus_babysitter_kill_child (pending_activation->babysitter);
+ if (pending_activation->babysitter)
+ _dbus_babysitter_kill_child (pending_activation->babysitter);
dbus_error_init (&error);
@@ -1221,6 +1236,10 @@ bus_activation_activate_service (BusActivation *activation,
DBusString service_str;
char *argv[2];
dbus_bool_t retval;
+ DBusHashIter iter;
+ dbus_bool_t activated;
+
+ activated = TRUE;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -1328,6 +1347,16 @@ bus_activation_activate_service (BusActivation *activation,
return FALSE;
}
+ pending_activation->exec = _dbus_strdup (entry->exec);
+ if (!pending_activation->exec)
+ {
+ _dbus_verbose ("Failed to copy service exec for pending activation\n");
+ BUS_SET_OOM (error);
+ bus_pending_activation_unref (pending_activation);
+ bus_pending_activation_entry_free (pending_activation_entry);
+ return FALSE;
+ }
+
pending_activation->timeout =
_dbus_timeout_new (bus_context_get_activation_timeout (activation->context),
pending_activation_timed_out,
@@ -1371,7 +1400,20 @@ bus_activation_activate_service (BusActivation *activation,
pending_activation->n_entries += 1;
pending_activation->activation->n_pending_activations += 1;
-
+
+ activated = FALSE;
+ _dbus_hash_iter_init (activation->pending_activations, &iter);
+ while (_dbus_hash_iter_next (&iter))
+ {
+ BusPendingActivation *p = _dbus_hash_iter_get_value (&iter);
+
+ if (strcmp (p->exec, entry->exec) == 0)
+ {
+ activated = TRUE;
+ break;
+ }
+ }
+
if (!_dbus_hash_table_insert_string (activation->pending_activations,
pending_activation->service_name,
pending_activation))
@@ -1383,7 +1425,7 @@ bus_activation_activate_service (BusActivation *activation,
return FALSE;
}
}
-
+
if (!add_cancel_pending_to_transaction (transaction, pending_activation))
{
_dbus_verbose ("Failed to add pending activation cancel hook to transaction\n");
@@ -1396,14 +1438,20 @@ bus_activation_activate_service (BusActivation *activation,
/* FIXME we need to support a full command line, not just a single
* argv[0]
*/
-
+
+ if (activated == TRUE)
+ {
+ pending_activation->babysitter = NULL;
+ return TRUE;
+ }
+
/* Now try to spawn the process */
argv[0] = entry->exec;
argv[1] = NULL;
if (!_dbus_spawn_async_with_babysitter (&pending_activation->babysitter, argv,
- child_setup, activation,
- error))
+ child_setup, activation,
+ error))
{
_dbus_verbose ("Failed to spawn child\n");
_DBUS_ASSERT_ERROR_IS_SET (error);
@@ -1414,7 +1462,7 @@ bus_activation_activate_service (BusActivation *activation,
if (!_dbus_babysitter_set_watch_functions (pending_activation->babysitter,
add_babysitter_watch,
- remove_babysitter_watch,
+ remove_babysitter_watch,
NULL,
pending_activation,
NULL))