X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fmanager.c;h=aa4baaacc8bdb01611b93ce93b10dc28bc40d149;hb=d420282b28f50720e233ccb1c02547c562195653;hp=b50182bce53c6bfa039f5032bfc1857aecd043f2;hpb=828db5d84afbf4e6e7060b5da170114a5886b339;p=elogind.git diff --git a/src/core/manager.c b/src/core/manager.c index b50182bce..aa4baaacc 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -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); @@ -456,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; @@ -472,6 +490,12 @@ int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) { 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")) @@ -662,6 +686,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); @@ -672,6 +697,7 @@ void manager_free(Manager *m) { manager_close_idle_pipe(m); + udev_unref(m->udev); sd_event_unref(m->event); free(m->notify_socket); @@ -1119,32 +1145,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) { @@ -1679,9 +1700,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;