X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fmanager.c;h=65cb73cc9f9eaac0158811ba3496b44bbbac2cee;hb=f5f6d0e25574dd63fb605b81fa7767dd71c454db;hp=f2f473b9f2f0338634d90e60b86f4276ba6a0700;hpb=9d5a3757c3e5bc2266053dbadb4a542a6dd5e7b8;p=elogind.git diff --git a/src/core/manager.c b/src/core/manager.c index f2f473b9f..65cb73cc9 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 { @@ -306,7 +307,7 @@ static int enable_special_signals(Manager *m) { } 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; @@ -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; @@ -2275,8 +2293,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; }