-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
return job_merging_table[(a - 1) * a / 2 + b];
}
-bool job_later_link_matters(Job *j, JobType type, unsigned generation) {
- JobDependency *l;
-
- assert(j);
-
- j->generation = generation;
-
- LIST_FOREACH(subject, l, j->subject_list) {
- UnitActiveState state = _UNIT_ACTIVE_STATE_INVALID;
-
- /* Have we seen this before? */
- if (l->object->generation == generation)
- continue;
-
- state = unit_active_state(l->object->unit);
- switch (type) {
-
- case JOB_START:
- return IN_SET(state, UNIT_INACTIVE, UNIT_FAILED) ||
- job_later_link_matters(l->object, type, generation);
-
- case JOB_STOP:
- return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING) ||
- job_later_link_matters(l->object, type, generation);
-
- default:
- assert_not_reached("Invalid job type");
- }
- }
-
- return false;
-}
-
-bool job_is_redundant(Job *j, unsigned generation) {
-
- assert(j);
-
- UnitActiveState state = unit_active_state(j->unit);
- switch (j->type) {
+bool job_type_is_redundant(JobType a, UnitActiveState b) {
+ switch (a) {
case JOB_START:
- return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING) && !job_later_link_matters(j, JOB_START, generation);
+ return IN_SET(b, UNIT_ACTIVE, UNIT_RELOADING);
case JOB_STOP:
- return IN_SET(state, UNIT_INACTIVE, UNIT_FAILED) && !job_later_link_matters(j, JOB_STOP, generation);
+ return IN_SET(b, UNIT_INACTIVE, UNIT_FAILED);
case JOB_VERIFY_ACTIVE:
- return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING);
+ return IN_SET(b, UNIT_ACTIVE, UNIT_RELOADING);
case JOB_RELOAD:
return
- state == UNIT_RELOADING;
+ b == UNIT_RELOADING;
case JOB_RESTART:
return
- state == UNIT_ACTIVATING;
+ b == UNIT_ACTIVATING;
case JOB_NOP:
return true;
}
static bool job_is_runnable(Job *j) {
- Iterator i;
Unit *other;
void *v;
if (j->type == JOB_NOP)
return true;
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER], i)
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER])
if (other->job && job_compare(j, other->job, UNIT_AFTER) > 0) {
log_unit_debug(j->unit,
"starting held back, waiting for: %s",
return false;
}
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE], i)
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE])
if (other->job && job_compare(j, other->job, UNIT_BEFORE) > 0) {
log_unit_debug(j->unit,
"stopping held back, waiting for: %s",
static void job_fail_dependencies(Unit *u, UnitDependency d) {
Unit *other;
- Iterator i;
void *v;
assert(u);
- HASHMAP_FOREACH_KEY(v, other, u->dependencies[d], i) {
+ HASHMAP_FOREACH_KEY(v, other, u->dependencies[d]) {
Job *j = other->job;
if (!j)
Unit *u;
Unit *other;
JobType t;
- Iterator i;
void *v;
assert(j);
j->result = result;
- log_unit_debug(u, "Job %" PRIu32 " %s/%s finished, result=%s", j->id, u->id, job_type_to_string(t), job_result_to_string(result));
+ log_unit_debug(u, "Job %" PRIu32 " %s/%s finished, result=%s",
+ j->id, u->id, job_type_to_string(t), job_result_to_string(result));
- /* If this job did nothing to respective unit we don't log the status message */
+ /* If this job did nothing to the respective unit we don't log the status message */
if (!already)
job_emit_done_status_message(u, j->id, t, result);
finish:
/* Try to start the next jobs that can be started */
- HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_AFTER], i)
+ HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_AFTER])
if (other->job) {
job_add_to_run_queue(other->job);
job_add_to_gc_queue(other->job);
}
- HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_BEFORE], i)
+ HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_BEFORE])
if (other->job) {
job_add_to_run_queue(other->job);
job_add_to_gc_queue(other->job);
bool job_may_gc(Job *j) {
Unit *other;
- Iterator i;
void *v;
assert(j);
return false;
/* The logic is inverse to job_is_runnable, we cannot GC as long as we block any job. */
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE], i)
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE])
if (other->job && job_compare(j, other->job, UNIT_BEFORE) < 0)
return false;
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER], i)
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER])
if (other->job && job_compare(j, other->job, UNIT_AFTER) < 0)
return false;
_cleanup_free_ Job** list = NULL;
size_t n = 0, n_allocated = 0;
Unit *other = NULL;
- Iterator i;
void *v;
/* Returns a list of all pending jobs that need to finish before this job may be started. */
return 0;
}
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER], i) {
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER]) {
if (!other->job)
continue;
if (job_compare(j, other->job, UNIT_AFTER) <= 0)
list[n++] = other->job;
}
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE], i) {
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE]) {
if (!other->job)
continue;
if (job_compare(j, other->job, UNIT_BEFORE) <= 0)
size_t n = 0, n_allocated = 0;
Unit *other = NULL;
void *v;
- Iterator i;
assert(j);
assert(ret);
/* Returns a list of all pending jobs that are waiting for this job to finish. */
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE], i) {
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE]) {
if (!other->job)
continue;
list[n++] = other->job;
}
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER], i) {
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER]) {
if (!other->job)
continue;