chiark / gitweb /
core: set some event source priorities to enforce dispatching order
[elogind.git] / src / core / manager.c
index 86de0e3fbfad4eb003254392d89ce8962a2b9630..ba4dab3b86c919e8f79691c543beb3036a082c59 100644 (file)
@@ -95,6 +95,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
 static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
 static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
 static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
+static int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
 
 static int manager_setup_notify(Manager *m) {
         union {
@@ -367,6 +368,11 @@ static int manager_setup_signals(Manager *m) {
         if (r < 0)
                 return r;
 
+        /* Process signals a bit earlier than the rest of things */
+        r = sd_event_source_set_priority(m->signal_event_source, -5);
+        if (r < 0)
+                return r;
+
         if (m->running_as == SYSTEMD_SYSTEM)
                 return enable_special_signals(m);
 
@@ -397,6 +403,8 @@ static int manager_default_environment(Manager *m) {
         if (!m->environment)
                 return -ENOMEM;
 
+        strv_sort(m->environment);
+
         return 0;
 }
 
@@ -454,6 +462,18 @@ int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) {
         if (r < 0)
                 goto fail;
 
+        r = sd_event_add_defer(m->event, manager_dispatch_run_queue, m, &m->run_queue_event_source);
+        if (r < 0)
+                goto fail;
+
+        r = sd_event_source_set_priority(m->run_queue_event_source, SD_EVENT_PRIORITY_IDLE);
+        if (r < 0)
+                goto fail;
+
+        r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_OFF);
+        if (r < 0)
+                goto fail;
+
         r = manager_setup_signals(m);
         if (r < 0)
                 goto fail;
@@ -660,6 +680,7 @@ void manager_free(Manager *m) {
         sd_event_source_unref(m->time_change_event_source);
         sd_event_source_unref(m->jobs_in_progress_event_source);
         sd_event_source_unref(m->idle_pipe_event_source);
+        sd_event_source_unref(m->run_queue_event_source);
 
         if (m->signal_fd >= 0)
                 close_nointr_nofail(m->signal_fd);
@@ -1117,32 +1138,27 @@ void manager_clear_jobs(Manager *m) {
                 job_finish_and_invalidate(j, JOB_CANCELED, false);
 }
 
-static unsigned manager_dispatch_run_queue(Manager *m) {
+static int manager_dispatch_run_queue(sd_event_source *source, void *userdata) {
+        Manager *m = userdata;
         Job *j;
-        unsigned n = 0;
-
-        if (m->dispatching_run_queue)
-                return 0;
 
-        m->dispatching_run_queue = true;
+        assert(source);
+        assert(m);
 
         while ((j = m->run_queue)) {
                 assert(j->installed);
                 assert(j->in_run_queue);
 
                 job_run_and_invalidate(j);
-                n++;
         }
 
-        m->dispatching_run_queue = false;
-
         if (m->n_running_jobs > 0)
                 manager_watch_jobs_in_progress(m);
 
         if (m->n_on_console > 0)
                 manager_watch_idle_pipe(m);
 
-        return n;
+        return 1;
 }
 
 static unsigned manager_dispatch_dbus_queue(Manager *m) {
@@ -1677,9 +1693,6 @@ int manager_loop(Manager *m) {
                 if (manager_dispatch_cgroup_queue(m) > 0)
                         continue;
 
-                if (manager_dispatch_run_queue(m) > 0)
-                        continue;
-
                 if (manager_dispatch_dbus_queue(m) > 0)
                         continue;
 
@@ -1806,6 +1819,9 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
         if (m->running_as != SYSTEMD_SYSTEM)
                 return;
 
+        if (detect_container(NULL) > 0)
+                return;
+
         if (u->type != UNIT_SERVICE &&
             u->type != UNIT_MOUNT &&
             u->type != UNIT_SWAP)
@@ -2270,8 +2286,9 @@ void manager_check_finished(Manager *m) {
         if (m->n_running_jobs == 0)
                 m->jobs_in_progress_event_source = sd_event_source_unref(m->jobs_in_progress_event_source);
 
-        if (hashmap_size(m->jobs) > 0 && m->jobs_in_progress_event_source) {
-                sd_event_source_set_time(m->jobs_in_progress_event_source, JOBS_IN_PROGRESS_PERIOD_SEC);
+        if (hashmap_size(m->jobs) > 0) {
+                if (m->jobs_in_progress_event_source)
+                        sd_event_source_set_time(m->jobs_in_progress_event_source, JOBS_IN_PROGRESS_PERIOD_SEC);
                 return;
         }
 
@@ -2504,7 +2521,7 @@ int manager_environment_add(Manager *m, char **minus, char **plus) {
         if (b != l)
                 strv_free(b);
 
-        m->environment = l;
+        m->environment = strv_sort(l);
         return 0;
 }