From ac1135be1f18443981211e38fc66437f147c6aee Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 26 Jan 2010 19:25:02 +0100 Subject: [PATCH] get rid of 'linked' notion for objects --- job.c | 11 +++-- job.h | 2 +- manager.c | 31 +++++--------- name.c | 122 ++++++++++-------------------------------------------- name.h | 5 +-- 5 files changed, 43 insertions(+), 128 deletions(-) diff --git a/job.c b/job.c index a2100e331..4daed49f2 100644 --- a/job.c +++ b/job.c @@ -30,12 +30,12 @@ void job_free(Job *j) { assert(j); /* Detach from next 'bigger' objects */ - if (j->linked) { + if (j->installed) { if (j->name->meta.job == j) j->name->meta.job = NULL; hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id)); - j->linked = false; + j->installed = false; } /* Detach from next 'smaller' objects */ @@ -260,7 +260,7 @@ bool job_is_runnable(Job *j) { Name *other; assert(j); - assert(j->linked); + assert(j->installed); /* Checks whether there is any job running for the names this * job needs to be running after (in the case of a 'positive' @@ -308,7 +308,9 @@ bool job_is_runnable(Job *j) { int job_run_and_invalidate(Job *j) { int r; + assert(j); + assert(j->installed); if (j->in_run_queue) { LIST_REMOVE(Job, run_queue, j->manager->run_queue, j); @@ -401,6 +403,7 @@ int job_finish_and_invalidate(Job *j, bool success) { Iterator i; assert(j); + assert(j->installed); /* Patch restart jobs so that they become normal start jobs */ if (success && (j->type == JOB_RESTART || j->type == JOB_TRY_RESTART)) { @@ -460,7 +463,7 @@ int job_finish_and_invalidate(Job *j, bool success) { void job_schedule_run(Job *j) { assert(j); - assert(j->linked); + assert(j->installed); if (j->in_run_queue) return; diff --git a/job.h b/job.h index 129601164..5527d6e42 100644 --- a/job.h +++ b/job.h @@ -69,7 +69,7 @@ struct Job { JobType type; JobState state; - bool linked:1; + bool installed:1; bool in_run_queue:1; bool matters_to_anchor:1; bool forced:1; diff --git a/manager.c b/manager.c index 90e17b249..7950a8a7c 100644 --- a/manager.c +++ b/manager.c @@ -95,7 +95,7 @@ static void transaction_delete_job(Manager *m, Job *j) { manager_transaction_unlink_job(m, j); - if (!j->linked) + if (!j->installed) job_free(j); } @@ -115,7 +115,7 @@ static void transaction_abort(Manager *m) { assert(m); while ((j = hashmap_first(m->transaction_jobs))) - if (j->linked) + if (j->installed) transaction_delete_job(m, j); else job_free(j); @@ -162,7 +162,7 @@ static void transaction_merge_and_delete_job(Manager *m, Job *j, Job *other, Job assert(j); assert(other); assert(j->name == other->name); - assert(!j->linked); + assert(!j->installed); /* Merges 'other' into 'j' and then deletes j. */ @@ -295,7 +295,7 @@ static int transaction_merge_jobs(Manager *m) { job_type_merge(&t, j->name->meta.job->type); /* Might fail. Which is OK */ while ((k = j->transaction_next)) { - if (j->linked) { + if (j->installed) { transaction_merge_and_delete_job(m, k, j, t); j = k; } else @@ -348,7 +348,7 @@ static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned for (k = from; k; k = (k->generation == generation ? k->marker : NULL)) { - if (!k->linked && + if (!k->installed && !name_matters_to_anchor(k->name, k)) { /* Ok, we can drop this one, so let's * do so. */ @@ -513,7 +513,7 @@ static int transaction_apply(Manager *m, JobMode mode) { assert(!j->transaction_prev); assert(!j->transaction_next); - if (j->linked) + if (j->installed) continue; if ((r = hashmap_put(m->jobs, UINT32_TO_PTR(j->id), j)) < 0) @@ -521,14 +521,14 @@ static int transaction_apply(Manager *m, JobMode mode) { } while ((j = hashmap_steal_first(m->transaction_jobs))) { - if (j->linked) + if (j->installed) continue; if (j->name->meta.job) job_free(j->name->meta.job); j->name->meta.job = j; - j->linked = true; + j->installed = true; /* We're fully installed. Now let's free data we don't * need anymore. */ @@ -549,7 +549,7 @@ static int transaction_apply(Manager *m, JobMode mode) { rollback: HASHMAP_FOREACH(j, m->transaction_jobs, i) { - if (j->linked) + if (j->installed) continue; hashmap_remove(m->jobs, UINT32_TO_PTR(j->id)); @@ -822,7 +822,6 @@ static void dispatch_load_queue(Manager *m) { * tries to load its data until the queue is empty */ while ((meta = m->load_queue)) { - assert(meta->linked); assert(meta->in_load_queue); name_load(NAME(meta)); @@ -855,15 +854,7 @@ int manager_load_name(Manager *m, const char *name, Name **_ret) { return r; } - if ((r = name_link(ret)) < 0) { - name_free(ret); - return r; - } - - /* At this point the new entry is created and linked. However - * not loaded. Now load this entry and all its dependencies - * recursively */ - + name_add_to_load_queue(ret); dispatch_load_queue(m); *_ret = ret; @@ -914,7 +905,7 @@ void manager_dispatch_run_queue(Manager *m) { m->dispatching_run_queue = true; while ((j = m->run_queue)) { - assert(j->linked); + assert(j->installed); assert(j->in_run_queue); job_run_and_invalidate(j); diff --git a/name.c b/name.c index 05eafab6b..e88dc8583 100644 --- a/name.c +++ b/name.c @@ -83,8 +83,6 @@ Name *name_new(Manager *m) { n->meta.manager = m; n->meta.type = _NAME_TYPE_INVALID; - /* We don't link the name here, that is left for name_link() */ - return n; } @@ -110,6 +108,12 @@ int name_add_name(Name *n, const char *text) { return r; } + if ((r = hashmap_put(n->meta.manager->names, s, n)) < 0) { + set_remove(n->meta.names, s); + free(s); + return r; + } + n->meta.type = t; if (!n->meta.id) @@ -118,61 +122,14 @@ int name_add_name(Name *n, const char *text) { return 0; } -/* FIXME: Does not rollback on failure! */ -int name_link_names(Name *n, bool replace) { - char *t; - Iterator i; - int r; - +void name_add_to_load_queue(Name *n) { assert(n); - if (!n->meta.linked) - return 0; - - /* Link all names that aren't linked yet. */ - - SET_FOREACH(t, n->meta.names, i) - if (replace) { - if ((r = hashmap_replace(n->meta.manager->names, t, n)) < 0) - return r; - } else { - if ((r = hashmap_put(n->meta.manager->names, t, n)) < 0) - return r; - } - - return 0; -} - -int name_link(Name *n) { - int r; - - assert(n); - assert(!set_isempty(n->meta.names)); - assert(!n->meta.linked); - - if ((r = name_sanitize(n)) < 0) - return r; - - n->meta.linked = true; - - if ((r = name_link_names(n, false)) < 0) { - char *t; - Iterator i; - - /* Rollback the registered names */ - SET_FOREACH(t, n->meta.names, i) - hashmap_remove_value(n->meta.manager->names, t, n); - - n->meta.linked = false; - return r; - } - - if (n->meta.load_state == NAME_STUB) { - LIST_PREPEND(Meta, load_queue, n->meta.manager->load_queue, &n->meta); - n->meta.in_load_queue = true; - } + if (n->meta.load_state != NAME_STUB || n->meta.in_load_queue) + return; - return 0; + LIST_PREPEND(Meta, load_queue, n->meta.manager->load_queue, &n->meta); + n->meta.in_load_queue = true; } static void bidi_set_free(Name *name, Set *s) { @@ -184,13 +141,11 @@ static void bidi_set_free(Name *name, Set *s) { /* Frees the set and makes sure we are dropped from the * inverse pointers */ - if (name->meta.linked) { - SET_FOREACH(other, s, i) { - NameDependency d; + SET_FOREACH(other, s, i) { + NameDependency d; - for (d = 0; d < _NAME_DEPENDENCY_MAX; d++) - set_remove(other->meta.dependencies[d], name); - } + for (d = 0; d < _NAME_DEPENDENCY_MAX; d++) + set_remove(other->meta.dependencies[d], name); } set_free(s); @@ -198,21 +153,18 @@ static void bidi_set_free(Name *name, Set *s) { void name_free(Name *name) { NameDependency d; + Iterator i; char *t; assert(name); /* Detach from next 'bigger' objects */ - if (name->meta.linked) { - char *t; - Iterator i; - SET_FOREACH(t, name->meta.names, i) - hashmap_remove_value(name->meta.manager->names, t, name); + SET_FOREACH(t, name->meta.names, i) + hashmap_remove_value(name->meta.manager->names, t, name); - if (name->meta.in_load_queue) - LIST_REMOVE(Meta, load_queue, name->meta.manager->load_queue, &name->meta); - } + if (name->meta.in_load_queue) + LIST_REMOVE(Meta, load_queue, name->meta.manager->load_queue, &name->meta); if (name->meta.load_state == NAME_LOADED) if (NAME_VTABLE(name)->done) @@ -285,27 +237,6 @@ int name_merge(Name *name, Name *other) { if ((r = ensure_merge(&name->meta.dependencies[d], other->meta.dependencies[d])) < 0) return r; - /* Hookup new deps and names */ - if (name->meta.linked) { - if ((r = name_sanitize(name)) < 0) - return r; - - if ((r = name_link_names(name, true)) < 0) - return r; - } - - return 0; -} - -int name_sanitize(Name *n) { - NameDependency d; - - assert(n); - - /* Remove loops */ - for (d = 0; d < _NAME_DEPENDENCY_MAX; d++) - set_remove(n->meta.dependencies[d], n); - return 0; } @@ -467,19 +398,9 @@ int name_load(Name *name) { if ((r = NAME_VTABLE(name)->init(name)) < 0) goto fail; - if ((r = name_sanitize(name)) < 0) - goto fail_undo_init; - - if ((r = name_link_names(name, false)) < 0) - goto fail_undo_init; - name->meta.load_state = NAME_LOADED; return 0; -fail_undo_init: - if (NAME_VTABLE(name)->done) - NAME_VTABLE(name)->done(name); - fail: name->meta.load_state = NAME_FAILED; return r; @@ -893,6 +814,9 @@ int name_add_dependency(Name *n, NameDependency d, Name *other) { assert(inverse_table[d] != _NAME_DEPENDENCY_INVALID); assert(other); + if (n == other) + return 0; + if ((r = set_ensure_allocated(&n->meta.dependencies[d], trivial_hash_func, trivial_compare_func)) < 0) return r; diff --git a/name.h b/name.h index 17bb35d6a..df62767ec 100644 --- a/name.h +++ b/name.h @@ -108,7 +108,6 @@ struct Meta { * the job for it */ Job *job; - bool linked:1; bool in_load_queue:1; usec_t active_enter_timestamp; @@ -200,10 +199,8 @@ bool name_is_valid(const char *n); Name *name_new(Manager *m); void name_free(Name *name); -int name_link(Name *name); -int name_link_names(Name *name, bool replace); +void name_add_to_load_queue(Name *n); int name_merge(Name *name, Name *other); -int name_sanitize(Name *n); int name_load_fragment_and_dropin(Name *n); int name_load(Name *name); const char* name_id(Name *n); -- 2.30.2