aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-10-07 21:52:38 +0300
committerSergey Poznyakoff <gray@gnu.org>2020-10-07 21:55:22 +0300
commitfb34e87b914f7989d572d2aa667a7df7604cf6fa (patch)
tree0a07938919231d74531ebfc70dc072513bbd82d6
parent335acb7442226c0bbf73974aeeee5c5c92ba3484 (diff)
downloadtallyman-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.c112
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;

Return to:

Send suggestions and report system problems to the System administrator.