1 /* 2 * Copyright © 2016 Mozilla Foundation 3 * 4 * This program is made available under an ISC-style license. See the 5 * accompanying file LICENSE for details. 6 */ 7 8 #ifndef CUBEB_ARRAY_QUEUE_H 9 #define CUBEB_ARRAY_QUEUE_H 10 11 #include <assert.h> 12 #include <pthread.h> 13 #include <unistd.h> 14 15 #if defined(__cplusplus) 16 extern "C" { 17 #endif 18 19 typedef struct 20 { 21 void ** buf; 22 size_t num; 23 size_t writePos; 24 size_t readPos; 25 pthread_mutex_t mutex; 26 } array_queue; 27 array_queue_create(size_t num)28array_queue * array_queue_create(size_t num) 29 { 30 assert(num != 0); 31 array_queue * new_queue = (array_queue*)calloc(1, sizeof(array_queue)); 32 new_queue->buf = (void **)calloc(1, sizeof(void *) * num); 33 new_queue->readPos = 0; 34 new_queue->writePos = 0; 35 new_queue->num = num; 36 37 pthread_mutex_init(&new_queue->mutex, NULL); 38 39 return new_queue; 40 } 41 array_queue_destroy(array_queue * aq)42void array_queue_destroy(array_queue * aq) 43 { 44 assert(aq); 45 46 free(aq->buf); 47 pthread_mutex_destroy(&aq->mutex); 48 free(aq); 49 } 50 array_queue_push(array_queue * aq,void * item)51int array_queue_push(array_queue * aq, void * item) 52 { 53 assert(item); 54 55 pthread_mutex_lock(&aq->mutex); 56 int ret = -1; 57 if(aq->buf[aq->writePos % aq->num] == NULL) 58 { 59 aq->buf[aq->writePos % aq->num] = item; 60 aq->writePos = (aq->writePos + 1) % aq->num; 61 ret = 0; 62 } 63 // else queue is full 64 pthread_mutex_unlock(&aq->mutex); 65 return ret; 66 } 67 array_queue_pop(array_queue * aq)68void* array_queue_pop(array_queue * aq) 69 { 70 pthread_mutex_lock(&aq->mutex); 71 void * value = aq->buf[aq->readPos % aq->num]; 72 if(value) 73 { 74 aq->buf[aq->readPos % aq->num] = NULL; 75 aq->readPos = (aq->readPos + 1) % aq->num; 76 } 77 pthread_mutex_unlock(&aq->mutex); 78 return value; 79 } 80 array_queue_get_size(array_queue * aq)81size_t array_queue_get_size(array_queue * aq) 82 { 83 pthread_mutex_lock(&aq->mutex); 84 ssize_t r = aq->writePos - aq->readPos; 85 if (r < 0) { 86 r = aq->num + r; 87 assert(r >= 0); 88 } 89 pthread_mutex_unlock(&aq->mutex); 90 return (size_t)r; 91 } 92 93 #if defined(__cplusplus) 94 } 95 #endif 96 97 #endif //CUBE_ARRAY_QUEUE_H 98