X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink_queue.h;h=d075f1c8497b887ea17cc0e171c39a6c4fcda7f0;hb=HEAD;hp=511d0b3ccf5c52b72bed6a0a02c54b09a25ea65a;hpb=61d9b04f66055e61f0afdf8955ff890f4da39288;p=meshlink diff --git a/src/meshlink_queue.h b/src/meshlink_queue.h index 511d0b3c..665c4d6e 100644 --- a/src/meshlink_queue.h +++ b/src/meshlink_queue.h @@ -36,32 +36,83 @@ typedef struct meshlink_queue_item { struct meshlink_queue_item *next; } meshlink_queue_item_t; -static inline bool meshlink_queue_push(meshlink_queue_t *queue, void *data) { - meshlink_queue_item_t *item = malloc(sizeof *item); - if(!item) +static inline void meshlink_queue_init(meshlink_queue_t *queue) { + queue->head = NULL; + queue->tail = NULL; + pthread_mutex_init(&queue->mutex, NULL); +} + +static inline void meshlink_queue_exit(meshlink_queue_t *queue) { + pthread_mutex_destroy(&queue->mutex); +} + +static inline __attribute__((__warn_unused_result__)) bool meshlink_queue_push(meshlink_queue_t *queue, void *data) { + meshlink_queue_item_t *item = malloc(sizeof(*item)); + + if(!item) { return false; + } + item->data = data; item->next = NULL; - pthread_mutex_lock(&queue->mutex); - if(!queue->tail) + + if(pthread_mutex_lock(&queue->mutex) != 0) { + abort(); + } + + if(!queue->tail) { queue->head = queue->tail = item; - else + } else { queue->tail = queue->tail->next = item; + } + pthread_mutex_unlock(&queue->mutex); return true; } -static inline void *meshlink_queue_pop(meshlink_queue_t *queue) { +static inline __attribute__((__warn_unused_result__)) void *meshlink_queue_pop(meshlink_queue_t *queue) { meshlink_queue_item_t *item; - void *data; - pthread_mutex_lock(&queue->mutex); + + if(pthread_mutex_lock(&queue->mutex) != 0) { + abort(); + } + if((item = queue->head)) { queue->head = item->next; - if(!queue->head) + + if(!queue->head) { queue->tail = NULL; + } } + pthread_mutex_unlock(&queue->mutex); - data = item ? item->data : NULL; + + void *data = item ? item->data : NULL; + free(item); + return data; +} + +static inline __attribute__((__warn_unused_result__)) void *meshlink_queue_pop_cond(meshlink_queue_t *queue, pthread_cond_t *cond) { + meshlink_queue_item_t *item; + + if(pthread_mutex_lock(&queue->mutex) != 0) { + abort(); + } + + while(!queue->head) { + pthread_cond_wait(cond, &queue->mutex); + } + + item = queue->head; + queue->head = item->next; + + if(!queue->head) { + queue->tail = NULL; + } + + pthread_mutex_unlock(&queue->mutex); + + void *data = item->data; free(item); return data; }