diff --git a/HISTORY b/HISTORY index b0b370d..60c9085 100644 --- a/HISTORY +++ b/HISTORY @@ -1,5 +1,5 @@ -Version 1.44 2020-02-21 +Version 1.44 2020-02-24 * add test file src/tests/test_pthread_lock.c * add uniq_skiplist.[hc] * add function split_string_ex @@ -9,6 +9,7 @@ Version 1.44 2020-02-21 * add function is_network_error * add function fast_mpool_log_stats * add files: server_id_func.[hc] + * common_blocked_queue support pop all nodes Version 1.43 2019-12-25 * replace function call system to getExecResult, diff --git a/src/common_blocked_queue.c b/src/common_blocked_queue.c index 79dcc2f..89efa6d 100644 --- a/src/common_blocked_queue.c +++ b/src/common_blocked_queue.c @@ -161,3 +161,50 @@ void *common_blocked_queue_pop_ex(struct common_blocked_queue *queue, return data; } +struct common_blocked_node *common_blocked_queue_pop_all_nodes_ex( + struct common_blocked_queue *queue, const bool blocked) +{ + struct common_blocked_node *node; + int result; + + if ((result=pthread_mutex_lock(&(queue->lock))) != 0) + { + logError("file: "__FILE__", line: %d, " + "call pthread_mutex_lock fail, " + "errno: %d, error info: %s", + __LINE__, result, STRERROR(result)); + return NULL; + } + + if (queue->head == NULL) + { + if (blocked) + { + pthread_cond_wait(&(queue->cond), &(queue->lock)); + } + } + + node = queue->head; + queue->head = queue->tail = NULL; + if ((result=pthread_mutex_unlock(&(queue->lock))) != 0) + { + logError("file: "__FILE__", line: %d, " + "call pthread_mutex_unlock fail, " + "errno: %d, error info: %s", + __LINE__, result, STRERROR(result)); + } + + return node; +} + +void common_blocked_queue_free_all_nodes(struct common_blocked_queue *queue, + struct common_blocked_node *node) +{ + struct common_blocked_node *deleted; + + while (node != NULL) { + deleted = node; + node = node->next; + fast_mblock_free_object(&queue->mblock, deleted); + } +} diff --git a/src/common_blocked_queue.h b/src/common_blocked_queue.h index 0d0d0c0..f20f073 100644 --- a/src/common_blocked_queue.h +++ b/src/common_blocked_queue.h @@ -45,7 +45,8 @@ int common_blocked_queue_init_ex(struct common_blocked_queue *queue, void common_blocked_queue_destroy(struct common_blocked_queue *queue); -static inline void common_blocked_queue_terminate(struct common_blocked_queue *queue) +static inline void common_blocked_queue_terminate( + struct common_blocked_queue *queue) { pthread_cond_signal(&(queue->cond)); } @@ -65,15 +66,26 @@ int common_blocked_queue_push(struct common_blocked_queue *queue, void *data); void *common_blocked_queue_pop_ex(struct common_blocked_queue *queue, const bool blocked); -static inline void *common_blocked_queue_pop(struct common_blocked_queue *queue) -{ - return common_blocked_queue_pop_ex(queue, true); -} +#define common_blocked_queue_pop(queue) \ + common_blocked_queue_pop_ex(queue, true) -static inline void *common_blocked_queue_try_pop(struct common_blocked_queue *queue) -{ - return common_blocked_queue_pop_ex(queue, false); -} +#define common_blocked_queue_try_pop(queue) \ + common_blocked_queue_pop_ex(queue, false) + +struct common_blocked_node *common_blocked_queue_pop_all_nodes_ex( + struct common_blocked_queue *queue, const bool blocked); + +#define common_blocked_queue_pop_all_nodes(queue) \ + common_blocked_queue_pop_all_nodes_ex(queue, true) + +#define common_blocked_queue_try_pop_all_nodes(queue) \ + common_blocked_queue_pop_all_nodes_ex(queue, false) + +#define common_blocked_queue_free_one_node(queue, node) \ + fast_mblock_free_object(&queue->mblock, node) + +void common_blocked_queue_free_all_nodes(struct common_blocked_queue *queue, + struct common_blocked_node *node); #ifdef __cplusplus }