diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-01-05 17:22:10 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-01-05 17:54:59 +0100 |
commit | 9c3349e23b14db27e7ba45f82cf647899c563ea9 (patch) | |
tree | 387cb16085148be5626917ae4a83afdc3bc61d3e /src/core/job.c | |
parent | bbe05969ec5b8b89a20f052f63ebb3790c0c5574 (diff) |
core: rework counting of running jobs
Let's unify the code that counts the running jobs a bit, in order to
make sure we are less likely to miss one.
This is related to this bug:
https://bugs.freedesktop.org/show_bug.cgi?id=87349
However, it probably won't fix it fully, and I cannot reproduce the issue.
The change also adds an explicit assert change when the counter is off.
Diffstat (limited to 'src/core/job.c')
-rw-r--r-- | src/core/job.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/src/core/job.c b/src/core/job.c index a3ba7cf703..2129773ede 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -96,11 +96,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 +183,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 +210,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 +220,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 +239,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); @@ -484,8 +516,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 +580,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); } @@ -780,9 +810,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 +822,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 +1054,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; |