X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=job.c;h=d22ce19ee13490604d63fdb78e4cfb952a18061b;hb=e094e853a047e10f0d2989eed76b6aa430e3ea1a;hp=ec0baba5ee575417e7417d63c922ae999bf1611b;hpb=ceed357001a7543c62468c5b943cf80c2a644252;p=elogind.git diff --git a/job.c b/job.c index ec0baba5e..d22ce19ee 100644 --- a/job.c +++ b/job.c @@ -1,6 +1,7 @@ /*-*- Mode: C; c-basic-offset: 8 -*-*/ #include +#include #include "macro.h" #include "job.h" @@ -37,7 +38,7 @@ void job_free(Job *j) { hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id)); } - manager_transaction_delete_job(j->manager, j); + manager_transaction_unlink_job(j->manager, j); free(j); } @@ -127,7 +128,7 @@ void job_dependency_delete(Job *subject, Job *object, bool *matters) { job_dependency_free(l); } -void job_dump(Job *j, FILE*f, const char *prefix) { +const char* job_type_to_string(JobType t) { static const char* const job_type_table[_JOB_TYPE_MAX] = { [JOB_START] = "start", @@ -139,6 +140,15 @@ void job_dump(Job *j, FILE*f, const char *prefix) { [JOB_TRY_RESTART] = "try-restart", }; + + if (t < 0 || t >= _JOB_TYPE_MAX) + return "n/a"; + + return job_type_table[t]; +} + +void job_dump(Job *j, FILE*f, const char *prefix) { + static const char* const job_state_table[_JOB_STATE_MAX] = { [JOB_WAITING] = "waiting", [JOB_RUNNING] = "running", @@ -153,7 +163,7 @@ void job_dump(Job *j, FILE*f, const char *prefix) { "%s\tAction: %s → %s\n" "%s\tState: %s\n", prefix, j->id, - prefix, name_id(j->name), job_type_table[j->type], + prefix, name_id(j->name), job_type_to_string(j->type), prefix, job_state_table[j->state]); } @@ -168,3 +178,98 @@ bool job_is_anchor(Job *j) { return false; } + +static bool types_match(JobType a, JobType b, JobType c, JobType d) { + return + (a == c && b == d) || + (a == d && b == c); +} + +int job_type_merge(JobType *a, JobType b) { + if (*a == b) + return 0; + + /* Merging is associative! a merged with b merged with c is + * the same as a merged with c merged with b. */ + + /* Mergeability is transitive! if a can be merged with b and b + * with c then a also with c */ + + /* Also, if a merged with b cannot be merged with c, then + * either a or b cannot be merged with c either */ + + if (types_match(*a, b, JOB_START, JOB_VERIFY_STARTED)) + *a = JOB_START; + else if (types_match(*a, b, JOB_START, JOB_RELOAD) || + types_match(*a, b, JOB_START, JOB_RELOAD_OR_START) || + types_match(*a, b, JOB_VERIFY_STARTED, JOB_RELOAD_OR_START) || + types_match(*a, b, JOB_RELOAD, JOB_RELOAD_OR_START)) + *a = JOB_RELOAD_OR_START; + else if (types_match(*a, b, JOB_START, JOB_RESTART) || + types_match(*a, b, JOB_START, JOB_TRY_RESTART) || + types_match(*a, b, JOB_VERIFY_STARTED, JOB_RESTART) || + types_match(*a, b, JOB_RELOAD, JOB_RESTART) || + types_match(*a, b, JOB_RELOAD_OR_START, JOB_RESTART) || + types_match(*a, b, JOB_RELOAD_OR_START, JOB_TRY_RESTART) || + types_match(*a, b, JOB_RESTART, JOB_TRY_RESTART)) + *a = JOB_RESTART; + else if (types_match(*a, b, JOB_VERIFY_STARTED, JOB_RELOAD)) + *a = JOB_RELOAD; + else if (types_match(*a, b, JOB_VERIFY_STARTED, JOB_TRY_RESTART) || + types_match(*a, b, JOB_RELOAD, JOB_TRY_RESTART)) + *a = JOB_TRY_RESTART; + else + return -EEXIST; + + return 0; +} + +bool job_type_mergeable(JobType a, JobType b) { + return job_type_merge(&a, b) >= 0; +} + +bool job_type_is_superset(JobType a, JobType b) { + + /* Checks whether operation a is a "superset" of b */ + + if (a == b) + return true; + + switch (a) { + case JOB_START: + return b == JOB_VERIFY_STARTED; + + case JOB_RELOAD: + return b == JOB_VERIFY_STARTED; + + case JOB_RELOAD_OR_START: + return + b == JOB_RELOAD || + b == JOB_START; + + case JOB_RESTART: + return + b == JOB_START || + b == JOB_VERIFY_STARTED || + b == JOB_RELOAD || + b == JOB_RELOAD_OR_START || + b == JOB_TRY_RESTART; + + case JOB_TRY_RESTART: + return + b == JOB_VERIFY_STARTED || + b == JOB_RELOAD; + default: + return false; + + } +} + +bool job_type_is_conflicting(JobType a, JobType b) { + + /* Checks whether two types are "conflicting" */ + + return + (a == JOB_STOP && b != JOB_STOP) || + (b == JOB_STOP && a != JOB_STOP); +}