X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fjob.c;h=2ef9123ae4234a7f7f11a195aed00c98d86a9867;hp=a3ba7cf703f6aa5c850d5a15bea07d69461d8976;hb=103635db51044e6b56efda08bfe98ed78a218b75;hpb=0faacd470dfbd24f4c6504da6f04213aa05f9d19 diff --git a/src/core/job.c b/src/core/job.c index a3ba7cf70..2ef9123ae 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -19,10 +19,7 @@ along with systemd; If not, see . ***/ -#include #include -#include -#include #include "sd-id128.h" #include "sd-messages.h" @@ -30,8 +27,6 @@ #include "unit.h" #include "macro.h" #include "strv.h" -#include "load-fragment.h" -#include "load-dropin.h" #include "log.h" #include "dbus-job.h" #include "special.h" @@ -96,11 +91,39 @@ void job_free(Job *j) { free(j); } +static void job_set_state(Job *j, JobState state) { + assert(j); + assert(state >= 0); + assert(state < _JOB_STATE_MAX); + + if (j->state == state) + return; + + j->state = state; + + if (!j->installed) + return; + + if (j->state == JOB_RUNNING) + j->unit->manager->n_running_jobs++; + else { + assert(j->state == JOB_WAITING); + assert(j->unit->manager->n_running_jobs > 0); + + j->unit->manager->n_running_jobs--; + + if (j->unit->manager->n_running_jobs <= 0) + j->unit->manager->jobs_in_progress_event_source = sd_event_source_unref(j->unit->manager->jobs_in_progress_event_source); + } +} + void job_uninstall(Job *j) { Job **pj; assert(j->installed); + job_set_state(j, JOB_WAITING); + pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job; assert(*pj == j); @@ -155,6 +178,7 @@ Job* job_install(Job *j) { assert(!j->installed); assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION); + assert(j->state == JOB_WAITING); pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job; uj = *pj; @@ -181,8 +205,8 @@ Job* job_install(Job *j) { log_unit_debug(uj->unit->id, "Merged into running job, re-running: %s/%s as %u", uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id); - uj->state = JOB_WAITING; - uj->manager->n_running_jobs--; + + job_set_state(uj, JOB_WAITING); return uj; } } @@ -191,6 +215,7 @@ Job* job_install(Job *j) { /* Install the job */ *pj = j; j->installed = true; + j->manager->n_installed_jobs ++; log_unit_debug(j->unit->id, "Installed new job %s/%s as %u", @@ -209,15 +234,17 @@ int job_install_deserialized(Job *j) { } pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job; - if (*pj) { - log_unit_debug(j->unit->id, - "Unit %s already has a job installed. Not installing deserialized job.", - j->unit->id); + log_unit_debug(j->unit->id, "Unit %s already has a job installed. Not installing deserialized job.", j->unit->id); return -EEXIST; } + *pj = j; j->installed = true; + + if (j->state == JOB_RUNNING) + j->unit->manager->n_running_jobs++; + log_unit_debug(j->unit->id, "Reinstalled deserialized job %s/%s as %u", j->unit->id, job_type_to_string(j->type), (unsigned) j->id); @@ -290,8 +317,8 @@ void job_dump(Job *j, FILE*f, const char *prefix) { * the JOB_RELOAD_OR_START, which lies outside the lookup function's domain), * the following properties hold: * - * Merging is associative! A merged with B merged with C is the same as - * A merged with C merged with B. + * Merging is associative! A merged with B, and then merged with C is the same + * as A merged with the result of B merged with C. * * Mergeability is transitive! If A can be merged with B and B with C then * A also with C. @@ -484,8 +511,7 @@ int job_run_and_invalidate(Job *j) { if (!job_is_runnable(j)) return -EAGAIN; - j->state = JOB_RUNNING; - m->n_running_jobs++; + job_set_state(j, JOB_RUNNING); job_add_to_dbus_queue(j); /* While we execute this operation the job might go away (for @@ -549,10 +575,9 @@ int job_run_and_invalidate(Job *j) { r = job_finish_and_invalidate(j, JOB_ASSERT, true); else if (r == -ENOTSUP) r = job_finish_and_invalidate(j, JOB_UNSUPPORTED, true); - else if (r == -EAGAIN) { - j->state = JOB_WAITING; - m->n_running_jobs--; - } else if (r < 0) + else if (r == -EAGAIN) + job_set_state(j, JOB_WAITING); + else if (r < 0) r = job_finish_and_invalidate(j, JOB_FAILED, true); } @@ -734,7 +759,6 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) { DISABLE_WARNING_FORMAT_NONLITERAL; snprintf(buf, sizeof(buf), format, unit_description(u)); - char_array_0(buf); REENABLE_WARNING; if (t == JOB_START) { @@ -780,9 +804,6 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) { j->result = result; - if (j->state == JOB_RUNNING) - j->manager->n_running_jobs--; - log_unit_debug(u->id, "Job %s/%s finished, result=%s", u->id, job_type_to_string(t), job_result_to_string(result)); @@ -795,7 +816,7 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) { if (result == JOB_DONE && t == JOB_RESTART) { job_change_type(j, JOB_START); - j->state = JOB_WAITING; + job_set_state(j, JOB_WAITING); job_add_to_run_queue(j); @@ -1027,7 +1048,7 @@ int job_deserialize(Job *j, FILE *f, FDSet *fds) { if (s < 0) log_debug("Failed to parse job state %s", v); else - j->state = s; + job_set_state(j, s); } else if (streq(l, "job-override")) { int b;