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 {
} else {
/* Enable that we get SIGWINCH on kbrequest */
if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
- log_warning("Failed to enable kbrequest handling: %s", strerror(errno));
+ log_warning("Failed to enable kbrequest handling: %m");
}
return 0;
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);
if (!m->environment)
return -ENOMEM;
+ strv_sort(m->environment);
+
return 0;
}
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;
if (r < 0)
goto fail;
+ m->udev = udev_new();
+ if (!m->udev) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
if (running_as == SYSTEMD_SYSTEM)
try_bus_connect = reexecuting;
else if (getenv("DBUS_SESSION_BUS_ADDRESS"))
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);
manager_close_idle_pipe(m);
+ udev_unref(m->udev);
sd_event_unref(m->event);
free(m->notify_socket);
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) {
if (manager_dispatch_cgroup_queue(m) > 0)
continue;
- if (manager_dispatch_run_queue(m) > 0)
- continue;
-
if (manager_dispatch_dbus_queue(m) > 0)
continue;
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;
}
if (b != l)
strv_free(b);
- m->environment = l;
+ m->environment = strv_sort(l);
return 0;
}