manager_transaction_unlink_job(m, j);
- if (!j->linked)
+ if (!j->installed)
job_free(j);
}
assert(m);
while ((j = hashmap_first(m->transaction_jobs)))
- if (j->linked)
+ if (j->installed)
transaction_delete_job(m, j);
else
job_free(j);
assert(j);
assert(other);
assert(j->name == other->name);
- assert(!j->linked);
+ assert(!j->installed);
/* Merges 'other' into 'j' and then deletes j. */
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
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. */
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)
}
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. */
rollback:
HASHMAP_FOREACH(j, m->transaction_jobs, i) {
- if (j->linked)
+ if (j->installed)
continue;
hashmap_remove(m->jobs, UINT32_TO_PTR(j->id));
* 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));
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;
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);
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;
}
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)
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) {
/* 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);
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)
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;
}
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;
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;