diff --git a/include/villas/list.h b/include/villas/list.h index 7d15bf941..07fd58e9f 100644 --- a/include/villas/list.h +++ b/include/villas/list.h @@ -16,6 +16,8 @@ #include #include +#include "common.h" + #define LIST_CHUNKSIZE 16 /** Static list initialization */ @@ -23,7 +25,8 @@ .array = NULL, \ .length = 0, \ .capacity = 0, \ - .lock = PTHREAD_MUTEX_INITIALIZER \ + .lock = PTHREAD_MUTEX_INITIALIZER, \ + .state = STATE_INITIALIZED \ } #define list_length(list) ((list)->length) @@ -49,6 +52,7 @@ struct list { size_t capacity; /**< Size of list::array in elements */ size_t length; /**< Number of elements of list::array which are in use */ pthread_mutex_t lock; /**< A mutex to allow thread-safe accesses */ + enum state state; /**< The state of this list. */ }; /** Initialize a list. diff --git a/lib/api.c b/lib/api.c index 86b5ad668..4722dd7db 100644 --- a/lib/api.c +++ b/lib/api.c @@ -126,6 +126,9 @@ int api_http_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void case LWS_CALLBACK_ESTABLISHED: { struct web *w = (struct web *) lws_context_user(lws_get_context(wsi)); + if (w->api == NULL) + return -1; /** @todo return error message */ + api_session_init(s, w->api, API_MODE_WS); break; } @@ -245,8 +248,7 @@ int api_init(struct api *a, struct super_node *sn) int api_destroy(struct api *a) { - if (a->state == STATE_STARTED) - return -1; + assert(a->state != STATE_STARTED); a->state = STATE_DESTROYED; diff --git a/lib/list.c b/lib/list.c index 1d938e882..0a95ed9bf 100644 --- a/lib/list.c +++ b/lib/list.c @@ -10,6 +10,7 @@ #include #include "list.h" +#include "utils.h" /* Compare functions */ static int cmp_lookup(const void *a, const void *b) { @@ -32,18 +33,22 @@ static int cmp_sort(const void *a, const void *b, void *thunk) { void list_init(struct list *l) { + assert(l->state == STATE_DESTROYED); + pthread_mutex_init(&l->lock, NULL); l->length = 0; l->capacity = 0; - l->array = NULL; + l->state = STATE_INITIALIZED; } int list_destroy(struct list *l, dtor_cb_t destructor, bool release) { pthread_mutex_lock(&l->lock); + assert(l->state != STATE_DESTROYED); + list_foreach(void *p, l) { if (destructor) destructor(p); @@ -61,12 +66,16 @@ int list_destroy(struct list *l, dtor_cb_t destructor, bool release) pthread_mutex_unlock(&l->lock); pthread_mutex_destroy(&l->lock); + l->state = STATE_DESTROYED; + return 0; } void list_push(struct list *l, void *p) { pthread_mutex_lock(&l->lock); + + assert(l->state == STATE_INITIALIZED); /* Resize array if out of capacity */ if (l->length >= l->capacity) { @@ -86,6 +95,8 @@ void list_remove(struct list *l, void *p) pthread_mutex_lock(&l->lock); + assert(l->state == STATE_INITIALIZED); + for (int i = 0; i < l->length; i++) { if (l->array[i] == p) removed++; @@ -114,6 +125,8 @@ int list_count(struct list *l, cmp_cb_t cmp, void *ctx) pthread_mutex_lock(&l->lock); + assert(l->state == STATE_INITIALIZED); + list_foreach(void *e, l) { if (cmp(e, ctx) == 0) c++; @@ -129,6 +142,8 @@ void * list_search(struct list *l, cmp_cb_t cmp, void *ctx) void *e; pthread_mutex_lock(&l->lock); + + assert(l->state == STATE_INITIALIZED); list_foreach(e, l) { if (!cmp(e, ctx)) @@ -146,6 +161,8 @@ void list_sort(struct list *l, cmp_cb_t cmp) { pthread_mutex_lock(&l->lock); + assert(l->state == STATE_INITIALIZED); + qsort_r(l->array, l->length, sizeof(void *), cmp_sort, (void *) cmp); pthread_mutex_unlock(&l->lock); diff --git a/lib/log.c b/lib/log.c index de554f686..846fefd1c 100644 --- a/lib/log.c +++ b/lib/log.c @@ -97,8 +97,7 @@ int log_start(struct log *l) int log_stop(struct log *l) { - if (l->state != STATE_STARTED) - return -1; + assert(l->state == STATE_STARTED); l->state = STATE_STOPPED; @@ -107,8 +106,7 @@ int log_stop(struct log *l) int log_destroy(struct log *l) { - if (l->state == STATE_STARTED) - return -1; + assert(l->state != STATE_STARTED); l->state = STATE_DESTROYED; @@ -232,7 +230,7 @@ void debug(long class, const char *fmt, ...) int lvl = class & 0xFF; int fac = class & ~0xFF; - assert(log); + assert(log != NULL); if (((fac == 0) || (fac & log->facilities)) && (lvl <= log->level)) { va_start(ap, fmt); @@ -245,7 +243,7 @@ void info(const char *fmt, ...) { va_list ap; - assert(log); + assert(log != NULL); va_start(ap, fmt); log_vprint(log, LOG_LVL_INFO, fmt, ap); @@ -256,7 +254,7 @@ void warn(const char *fmt, ...) { va_list ap; - assert(log); + assert(log != NULL); va_start(ap, fmt); log_vprint(log, LOG_LVL_WARN, fmt, ap); @@ -267,7 +265,7 @@ void stats(const char *fmt, ...) { va_list ap; - assert(log); + assert(log != NULL); va_start(ap, fmt); log_vprint(log, LOG_LVL_STATS, fmt, ap); @@ -278,7 +276,7 @@ void error(const char *fmt, ...) { va_list ap; - assert(log); + assert(log != NULL); va_start(ap, fmt); log_vprint(log, LOG_LVL_ERROR, fmt, ap); @@ -292,7 +290,7 @@ void serror(const char *fmt, ...) va_list ap; char *buf = NULL; - assert(log); + assert(log != NULL); va_start(ap, fmt); vstrcatf(&buf, fmt, ap); @@ -309,7 +307,7 @@ void cerror(config_setting_t *cfg, const char *fmt, ...) va_list ap; char *buf = NULL; - assert(log); + assert(log != NULL); va_start(ap, fmt); vstrcatf(&buf, fmt, ap); diff --git a/lib/node.c b/lib/node.c index 5e365ed9f..bd4fbe0be 100644 --- a/lib/node.c +++ b/lib/node.c @@ -15,8 +15,7 @@ int node_init(struct node *n) { - if (n->state != STATE_DESTROYED) - return -1; + assert(n->state == STATE_DESTROYED); n->state = STATE_INITIALIZED; @@ -54,8 +53,7 @@ int node_parse(struct node *n, config_setting_t *cfg) int node_check(struct node *n) { - if (n->state != STATE_INITIALIZED || n->state != STATE_PARSED) - return -1; + assert(n->state != STATE_DESTROYED); if (n->vectorize <= 0) error("Invalid `vectorize` value %d for node %s. Must be natural number!", n->vectorize, node_name(n)); @@ -73,8 +71,7 @@ int node_start(struct node *n) { int ret; - if (n->state != STATE_CHECKED) - return -1; + assert(n->state == STATE_CHECKED); info("Starting node %s", node_name_long(n)); { INDENT @@ -93,8 +90,7 @@ int node_stop(struct node *n) { int ret; - if (n->state != STATE_STARTED) - return -1; + assert(n->state == STATE_STARTED); info("Stopping node %s", node_name(n)); { INDENT @@ -109,8 +105,7 @@ int node_stop(struct node *n) int node_destroy(struct node *n) { - if (n->state == STATE_STARTED) - return -1; + assert(n->state != STATE_DESTROYED && n->state != STATE_STARTED); if (n->_vt->destroy) n->_vt->destroy(n); diff --git a/lib/node_type.c b/lib/node_type.c index bbbfd4f1e..83fd068af 100644 --- a/lib/node_type.c +++ b/lib/node_type.c @@ -18,8 +18,7 @@ int node_type_start(struct node_type *vt, int argc, char *argv[], config_setting { int ret; - if (vt->state == STATE_STARTED) - return -1; + assert(vt->state != STATE_STARTED); info("Initializing " YEL("%s") " node type", plugin_name(vt)); { INDENT @@ -36,8 +35,7 @@ int node_type_stop(struct node_type *vt) { int ret; - if (vt->state != STATE_STARTED) - return -1; + assert(vt->state == STATE_STARTED); info("De-initializing " YEL("%s") " node type", plugin_name(vt)); { INDENT diff --git a/lib/plugin.c b/lib/plugin.c index 4341cbbb1..c5c86e251 100644 --- a/lib/plugin.c +++ b/lib/plugin.c @@ -9,7 +9,7 @@ #include "plugin.h" /** Global list of all known plugins */ -struct list plugins; +struct list plugins = LIST_INIT(); int plugin_init(struct plugin *p, char *name, char *path) { @@ -36,8 +36,7 @@ int plugin_unload(struct plugin *p) { int ret; - if (p->state != STATE_LOADED) - return -1; + assert(p->state == STATE_LOADED); ret = dlclose(p->handle); if (ret) @@ -50,8 +49,7 @@ int plugin_unload(struct plugin *p) int plugin_destroy(struct plugin *p) { - if (p->state == STATE_LOADED) - plugin_unload(p); + assert(p->state != STATE_DESTROYED && p->state != STATE_LOADED); if (p->path) free(p->path); diff --git a/lib/pool.c b/lib/pool.c index 5ec74a95c..e2398d875 100644 --- a/lib/pool.c +++ b/lib/pool.c @@ -14,8 +14,7 @@ int pool_init(struct pool *p, size_t cnt, size_t blocksz, const struct memtype * { int ret; - if (p->state != STATE_DESTROYED) - return -1; + assert(p->state == STATE_DESTROYED); /* Make sure that we use a block size that is aligned to the size of a cache line */ p->alignment = kernel_get_cacheline_size(); @@ -45,8 +44,7 @@ int pool_destroy(struct pool *p) { int ret; - if (p->state != STATE_INITIALIZED) - return -1; + assert(p->state == STATE_INITIALIZED); queue_destroy(&p->queue); diff --git a/lib/queue.c b/lib/queue.c index 408c63d83..10ef9ec3e 100644 --- a/lib/queue.c +++ b/lib/queue.c @@ -38,8 +38,7 @@ /** Initialize MPMC queue */ int queue_init(struct queue *q, size_t size, const struct memtype *mem) { - if (q->state != STATE_DESTROYED) - return -1; + assert(q->state == STATE_DESTROYED); /* Queue size must be 2 exponent */ if (!IS_POW2(size)) { @@ -69,9 +68,8 @@ int queue_destroy(struct queue *q) { int ret = 0; - if (q->state != STATE_INITIALIZED) - return -1; - + assert(q->state == STATE_INITIALIZED); + ret = memory_free(q->mem, q->buffer, (q->buffer_mask + 1) * sizeof(q->buffer[0])); if (ret == 0) diff --git a/lib/web.c b/lib/web.c index f3f7bb4df..601f2c288 100644 --- a/lib/web.c +++ b/lib/web.c @@ -191,15 +191,18 @@ int web_start(struct web *w) int web_stop(struct web *w) { + assert(w->state == STATE_STARTED); + lws_cancel_service(w->context); + + w->state = STATE_STOPPED; return 0; } int web_destroy(struct web *w) { - if (w->state == STATE_STARTED) - return -1; + assert(w->state != STATE_DESTROYED && w->state != STATE_STARTED); lws_context_destroy(w->context); @@ -210,5 +213,7 @@ int web_destroy(struct web *w) int web_service(struct web *w) { + assert(w->state == STATE_STARTED); + return lws_service(w->context, 10); }