X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=manager.c;h=ace480c4dd5f0185a6d22ec2386bd2f7a7483d00;hp=b574c6380dad18b6886851b1732efe7186c2eedc;hb=c0dafa4853b52741e9a4845419c00611426cefd8;hpb=86fbf370855aaa0c6e04d17bdd1d9d0c81bc5101 diff --git a/manager.c b/manager.c index b574c6380..ace480c4d 100644 --- a/manager.c +++ b/manager.c @@ -1,5 +1,24 @@ /*-*- Mode: C; c-basic-offset: 8 -*-*/ +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + #include #include #include @@ -646,7 +665,8 @@ static int transaction_apply(Manager *m, JobMode mode) { assert(!j->transaction_next); assert(!j->transaction_prev); - job_schedule_run(j); + job_add_to_run_queue(j); + job_add_to_dbus_queue(j); } /* As last step, kill all remaining job dependencies. */ @@ -881,6 +901,9 @@ static int transaction_add_job_and_dependencies(Manager *m, JobType type, Unit * /* JOB_VERIFY_STARTED, JOB_RELOAD require no dependency handling */ } + if (_ret) + *_ret = ret; + return 0; fail: @@ -898,7 +921,7 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool for log_debug("Trying to enqueue job %s/%s", unit_id(unit), job_type_to_string(type)); - if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, force, &ret))) { + if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, force, &ret)) < 0) { transaction_abort(m); return r; } @@ -906,7 +929,7 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool for if ((r = transaction_activate(m, mode)) < 0) return r; - log_debug("Enqueued job %s/%s", unit_id(unit), job_type_to_string(type)); + log_debug("Enqueued job %s/%s as %u", unit_id(unit), job_type_to_string(type), (unsigned) ret->id); if (_ret) *_ret = ret; @@ -927,14 +950,15 @@ Unit *manager_get_unit(Manager *m, const char *name) { return hashmap_get(m->units, name); } -void manager_dispatch_load_queue(Manager *m) { +unsigned manager_dispatch_load_queue(Manager *m) { Meta *meta; + unsigned n = 0; assert(m); /* Make sure we are not run recursively */ if (m->dispatching_load_queue) - return; + return 0; m->dispatching_load_queue = true; @@ -945,9 +969,11 @@ void manager_dispatch_load_queue(Manager *m) { assert(meta->in_load_queue); unit_load(UNIT(meta)); + n++; } m->dispatching_load_queue = false; + return n; } int manager_load_unit(Manager *m, const char *path, Unit **_ret) { @@ -985,6 +1011,8 @@ int manager_load_unit(Manager *m, const char *path, Unit **_ret) { } unit_add_to_load_queue(ret); + unit_add_to_dbus_queue(ret); + manager_dispatch_load_queue(m); *_ret = ret; @@ -1026,11 +1054,12 @@ void manager_clear_jobs(Manager *m) { job_free(j); } -void manager_dispatch_run_queue(Manager *m) { +unsigned manager_dispatch_run_queue(Manager *m) { Job *j; + unsigned n = 0; if (m->dispatching_run_queue) - return; + return 0; m->dispatching_run_queue = true; @@ -1039,9 +1068,42 @@ void manager_dispatch_run_queue(Manager *m) { assert(j->in_run_queue); job_run_and_invalidate(j); + n++; } m->dispatching_run_queue = false; + return n; +} + +unsigned manager_dispatch_dbus_queue(Manager *m) { + Job *j; + Meta *meta; + unsigned n = 0; + + assert(m); + + if (m->dispatching_dbus_queue) + return 0; + + m->dispatching_dbus_queue = true; + + while ((meta = m->dbus_unit_queue)) { + Unit *u = (Unit*) meta; + assert(u->meta.in_dbus_queue); + + bus_unit_send_change_signal(u); + n++; + } + + while ((j = m->dbus_job_queue)) { + assert(j->in_dbus_queue); + + bus_job_send_change_signal(j); + n++; + } + + m->dispatching_dbus_queue = false; + return n; } static int manager_dispatch_sigchld(Manager *m) { @@ -1153,7 +1215,7 @@ static int process_event(Manager *m, struct epoll_event *ev, bool *quit) { ssize_t k; /* Some timer event, to be dispatched to the units */ - if ((k = read(ev->data.fd, &v, sizeof(v))) != sizeof(v)) { + if ((k = read(w->fd, &v, sizeof(v))) != sizeof(v)) { if (k < 0 && (errno == EINTR || errno == EAGAIN)) break; @@ -1208,12 +1270,17 @@ int manager_loop(Manager *m) { sleep(1); } - manager_dispatch_run_queue(m); + if (manager_dispatch_load_queue(m) > 0) + continue; - if (m->request_bus_dispatch) { - bus_dispatch(m); + if (manager_dispatch_run_queue(m) > 0) + continue; + + if (bus_dispatch(m) > 0) + continue; + + if (manager_dispatch_dbus_queue(m) > 0) continue; - } if ((n = epoll_wait(m->epoll_fd, &event, 1, -1)) < 0) {