]> git.lizzy.rs Git - dragonstd.git/blob - queue.c
Fix missing lock release in map_trv
[dragonstd.git] / queue.c
1 #include <sched.h>
2 #include "queue.h"
3
4 void queue_ini(Queue *queue)
5 {
6         list_ini(&queue->lst);
7         queue->cnl = queue->fin = 0;
8         pthread_cond_init(&queue->cnd, NULL);
9         pthread_mutex_init(&queue->mtx, NULL);
10 }
11
12 void queue_dst(Queue *queue)
13 {
14         pthread_cond_destroy(&queue->cnd);
15         pthread_mutex_destroy(&queue->mtx);
16 }
17
18 void queue_clr(Queue *queue, Iterator iter, void *arg, Transformer trans)
19 {
20         list_clr(&queue->lst, iter, arg, trans);
21 }
22
23 bool queue_enq(Queue *queue, void *dat)
24 {
25         bool success = false;
26
27         pthread_mutex_lock(&queue->mtx);
28         if (! queue->fin) {
29                 success = true;
30                 list_apd(&queue->lst, dat);
31                 pthread_cond_signal(&queue->cnd);
32         }
33         pthread_mutex_unlock(&queue->mtx);
34
35         return success;
36 }
37
38 void *queue_deq(Queue *queue, Transformer trans)
39 {
40         void *dat = NULL;
41
42         pthread_mutex_lock(&queue->mtx);
43         while (! queue->cnl && ! dat) {
44                 ListNode **node = &queue->lst.fst;
45                 if (*node) {
46                         dat = (*node)->dat;
47                         list_nrm(&queue->lst, node);
48
49                         if (trans)
50                                 dat = trans(dat);
51                 } else {
52                         pthread_cond_wait(&queue->cnd, &queue->mtx);
53                 }
54         }
55         pthread_mutex_unlock(&queue->mtx);
56
57         return dat;
58 }
59
60 void queue_cnl(Queue *queue)
61 {
62         pthread_mutex_lock(&queue->mtx);
63         queue->cnl = 1;
64         pthread_cond_broadcast(&queue->cnd);
65         pthread_mutex_unlock(&queue->mtx);
66 }
67
68 void queue_fin(Queue *queue)
69 {
70         pthread_mutex_lock(&queue->mtx);
71         queue->fin = 1;
72         pthread_mutex_unlock(&queue->mtx);
73
74         for (;;) {
75                 pthread_mutex_lock(&queue->mtx);
76                 ListNode *node = queue->lst.fst;
77                 pthread_mutex_unlock(&queue->mtx);
78
79                 if (node)
80                         sched_yield();
81                 else
82                         break;
83         }
84 }