diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-10-07 21:52:38 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-10-07 21:55:22 +0300 |
commit | fb34e87b914f7989d572d2aa667a7df7604cf6fa (patch) | |
tree | 0a07938919231d74531ebfc70dc072513bbd82d6 | |
parent | 335acb7442226c0bbf73974aeeee5c5c92ba3484 (diff) | |
download | tallyman-fb34e87b914f7989d572d2aa667a7df7604cf6fa.tar.gz tallyman-fb34e87b914f7989d572d2aa667a7df7604cf6fa.tar.bz2 |
Rework instance lists.
* src/servdb.c (instance_head): New struct.
(INSTANCE_HEAD_INITIALIZER)
(INSTANCE_LIST_FOREACH): New macros.
(service, instance): Use a single member of struct instance_head
type instead of a pair of struct instance pointers.
(instance_head_init)
(instance_list_append,instance_list_unlink): New functions.
-rw-r--r-- | src/servdb.c | 112 |
1 files changed, 68 insertions, 44 deletions
diff --git a/src/servdb.c b/src/servdb.c index dd0f012..fa96242 100644 --- a/src/servdb.c +++ b/src/servdb.c @@ -7,9 +7,18 @@ unsigned ttl_instance_state = 60; +struct instance_head { + struct instance *prev, *next; +}; + +#define INSTANCE_HEAD_INITIALIZER { NULL, NULL } + +#define INSTANCE_LIST_FOREACH(p,l) \ + for (p = (l)->prev; p; p = p->link.next) + struct service { char *id; - struct instance *head, *tail; + struct instance_head head; pthread_mutex_t mutex; }; @@ -27,11 +36,50 @@ struct instance { enum instance_state state; time_t timestamp; char *error_message; - struct instance *prev, *next; + struct instance_head link; pthread_cond_t notbusy; /* Prevent simultaneous updates */ int busy:1; /* Node is in use if 1 */ }; +static inline void +instance_head_init(struct instance_head *head) +{ + head->prev = head->next = NULL; +} + +static inline void +instance_list_append(struct instance_head *list, struct instance *inst) +{ + inst->link.next = NULL; + inst->link.prev = list->prev; + if (list->next) + list->next->link.next = inst; + else + list->prev = inst; + list->next = inst; +} + +static inline void +instance_list_unlink(struct instance_head *list, struct instance *inst) +{ + struct instance *p; + + p = inst->link.prev; + if (p) + p->link.next = inst->link.next; + else + list->prev = inst->link.next; + + p = inst->link.next; + if (p) + p->link.prev = inst->link.prev; + else + list->next = inst->link.prev; + + instance_head_init(&inst->link); +} + + static struct service service[MAX_SERVICE]; static size_t service_count; @@ -92,7 +140,7 @@ service_add(char const *id, grecs_locus_t *loc) } service[service_count].id = grecs_strdup(id); - service[service_count].head = service[service_count].tail = NULL; + instance_head_init(&service[service_count].head); pthread_mutex_init(&service[service_count].mutex, NULL); service_count++; @@ -116,7 +164,7 @@ instance_alloc(char const *hostname) return NULL; } - inst->next = inst->prev = NULL; + instance_head_init(&inst->link); inst->busy = 1; pthread_cond_init(&inst->notbusy, NULL); @@ -137,60 +185,36 @@ instance_lock(struct instance *inst) static void instance_unlock(struct instance *inst) { - assert(inst->srv != NULL); if (inst->busy) { inst->busy = 0; pthread_cond_broadcast(&inst->notbusy); } } -static void instance_unlink(struct instance *inst); +static void instance_service_unlink(struct instance *inst); static void instance_free(struct instance *inst) { if (inst) { - instance_unlink(inst); + instance_service_unlink(inst); free(inst->hostname); free(inst); } } -static void -instance_link(struct instance *inst, struct service *srv) +static inline void +instance_service_link(struct instance *inst, struct service *srv) { inst->srv = srv; - inst->prev = srv->tail; - if (srv->tail) - srv->tail->next = inst; - else - srv->head = inst; - srv->tail = inst; + instance_list_append(&srv->head, inst); } -static void -instance_unlink(struct instance *inst) +static inline void +instance_service_unlink(struct instance *inst) { - struct service *srv = inst->srv; - struct instance *p; - - if (!srv) - return; - - p = inst->prev; - if (p) - p->next = inst->next; - else - srv->head = inst->next; - - p = inst->next; - if (p) - p->prev = inst->prev; - else - srv->tail = inst->prev; - - inst->srv = NULL; - inst->next = inst->prev = NULL; + if (inst->srv) + instance_list_unlink(&inst->srv->head, inst); } static inline int @@ -203,7 +227,7 @@ static struct instance * instance_by_hostname(char const *hostname, struct service *srv) { struct instance *inst; - for (inst = srv->head; inst; inst = inst->next) + INSTANCE_LIST_FOREACH(inst, &srv->head) if (strcmp(inst->hostname, hostname) == 0) return inst; return NULL; @@ -254,7 +278,7 @@ servdb_update(struct json_value *obj) pthread_mutex_unlock(&srv->mutex); return -1; } - instance_link(inst, srv); + instance_service_link(inst, srv); } else instance_lock(inst); @@ -311,7 +335,7 @@ servdb_serviceInstances(size_t idx) if (idx > service_count) return -1; pthread_mutex_lock(&service[idx].mutex); - for (inst = service[idx].head; inst; inst = inst->next) { + INSTANCE_LIST_FOREACH(inst, &service[idx].head) { if (instance_is_running(inst)) { result++; } @@ -524,7 +548,7 @@ instanceTable_load(netsnmp_cache *cache, void *vmagic) struct instance *inst; pthread_mutex_lock(&service[i].mutex); - for (inst = service[i].head; inst; inst = inst->next) { + INSTANCE_LIST_FOREACH(inst, &service[i].head) { instance_lock(inst); rc = instanceTable_load_row(idx, inst, service[i].id, @@ -560,10 +584,10 @@ invalidator_thread(void *p) int invalidate = 0; for (i = 0; i < service_count; i++) { pthread_mutex_lock(&service[i].mutex); - for (inst = service[i].head; inst; inst = inst->next) { + INSTANCE_LIST_FOREACH(inst, &service[i].head) { instance_lock(inst); - if (inst->state != instance_state_expired - && now - inst->timestamp > ttl_instance_state) + if (inst->state != instance_state_expired && + now - inst->timestamp > ttl_instance_state) inst->state = instance_state_expired; instance_unlock(inst); invalidate = 1; |