return n;
}
+int name_link_names(Name *n) {
+ char *t;
+ void *state;
+ int r;
+
+ assert(n);
+
+ if (!n->meta.linked)
+ return 0;
+
+ /* Link all names that aren't linked yet */
+
+ SET_FOREACH(t, n->meta.names, state)
+ if ((r = hashmap_put(n->meta.manager->names, t, n)) < 0) {
+
+ if (r == -EEXIST && hashmap_get(n->meta.manager->names, t) == n)
+ continue;
+
+ return r;
+ }
+
+ return 0;
+}
+
int name_link(Name *n) {
- char **t;
int r;
- void *state;
assert(n);
assert(!set_isempty(n->meta.names));
assert(!n->meta.linked);
- SET_FOREACH(t, n->meta.names, state)
- if ((r = hashmap_put(n->meta.manager->names, t, n)) < 0)
- goto fail;
+ n->meta.linked = true;
- if (n->meta.state == NAME_STUB)
- LIST_PREPEND(Meta, n->meta.manager->load_queue, &n->meta);
+ if ((r = name_link_names(n) < 0)) {
+ char *t;
+ void *state;
- n->meta.linked = true;
+ /* Rollback the registered names */
+ SET_FOREACH(t, n->meta.names, state)
+ hashmap_remove(n->meta.manager->names, t);
- return 0;
+ n->meta.linked = false;
+ return r;
+ }
-fail:
- SET_FOREACH(t, n->meta.names, state)
- assert_se(hashmap_remove(n->meta.manager->names, t) == n);
+ if (n->meta.state == NAME_STUB)
+ LIST_PREPEND(Meta, n->meta.manager->load_queue, &n->meta);
- return r;
+ return 0;
}
static void bidi_set_free(Name *name, Set *s) {
Name *other;
assert(name);
- assert(s);
/* Frees the set and makes sure we are dropped from the
* inverse pointers */
/* Detach from next 'bigger' objects */
if (name->meta.linked) {
- char **t;
+ char *t;
void *state;
SET_FOREACH(t, name->meta.names, state)
Socket *s = SOCKET(name);
for (i = 0; i < s->n_fds; i++)
- nointr_close(s->fds[i]);
+ close_nointr(s->fds[i]);
break;
}
if ((r = ensure_merge(&name->meta.dependencies[d], other->meta.dependencies[d])) < 0)
return r;
+ if (name->meta.linked)
+ if ((r = name_link_names(name)) < 0)
+ return r;
+
return 0;
}
+
+const char* name_id(Name *n) {
+ assert(n);
+
+ return set_first(n->meta.names);
+}
+
+void name_dump(Name *n, FILE *f) {
+
+ static const char* const state_table[_NAME_STATE_MAX] = {
+ [NAME_STUB] = "stub",
+ [NAME_LOADED] = "loaded",
+ [NAME_FAILED] = "failed"
+ };
+
+ static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
+ [SOCKET_DEAD] = "dead",
+ [SOCKET_BEFORE] = "before",
+ [SOCKET_START_PRE] = "start-pre",
+ [SOCKET_START] = "start",
+ [SOCKET_START_POST] = "start-post",
+ [SOCKET_LISTENING] = "listening",
+ [SOCKET_RUNNING] = "running",
+ [SOCKET_STOP_PRE] = "stop-pre",
+ [SOCKET_STOP] = "stop",
+ [SOCKET_STOP_POST] = "stop-post",
+ [SOCKET_MAINTAINANCE] = "maintainance"
+ };
+
+ void *state;
+ char *t;
+
+ assert(n);
+
+ fprintf(f,
+ "Name %s\n"
+ "\tDescription: %s\n"
+ "\tState: %s\n",
+ name_id(n),
+ n->meta.description ? n->meta.description : name_id(n),
+ state_table[n->meta.state]);
+
+ fprintf(f, "\tNames: ");
+ SET_FOREACH(t, n->meta.names, state)
+ fprintf(f, "%s ", t);
+ fprintf(f, "\n");
+
+ switch (n->meta.type) {
+ case NAME_SOCKET: {
+ int r;
+ char *s = NULL;
+ const char *t;
+
+ if ((r = address_print(&n->socket.address, &s)) < 0)
+ t = strerror(-r);
+ else
+ t = s;
+
+ fprintf(f, "\t%s in state %s\n", t, socket_state_table[n->socket.state]);
+ free(s);
+ break;
+ }
+
+ default:
+ ;
+ }
+
+ if (n->meta.job) {
+ fprintf(f, "\t");
+ job_dump(n->meta.job, f);
+ }
+}