]> git.lizzy.rs Git - dragonstd.git/blob - queue.h
Add array_idx
[dragonstd.git] / queue.h
1 /*
2         Queue
3         -----
4
5         Thread safe FIFO data structure, using a List.
6         Useful for working with producer/consumer threads.
7 */
8
9 #ifndef _DRAGONSTD_QUEUE_H_ // include guard
10 #define _DRAGONSTD_QUEUE_H_
11
12 #include <pthread.h>       // for pthread_cond_t, pthread_mutex_t
13 #include <stdbool.h>       // for bool
14 #include "list.h"          // for List
15
16 typedef struct {
17         /* private */
18         List lst;            // list containing data
19         unsigned int cnl: 1; // cancel state
20         unsigned int fin: 1; // finish state
21         pthread_cond_t cnd;  // condition variable for notifying consumer
22         pthread_mutex_t mtx; // mutex to protect the condition variable
23 } Queue;
24
25 void queue_ini(Queue *queue);
26 /*
27         Initializes the queue.
28
29         The queue should be uninitialized or deleted when passed to this function.
30 */
31
32 void queue_dst(Queue *queue);
33 /*
34         Destroy the queue.
35
36         Afterwards, the queue should no longer be used.
37
38         This does not clear the underling list. Use queue_fin or queue_clr to make sure the
39                 list is cleared before calling this function.
40 */
41
42 void queue_clr(Queue *queue, void *iter, void *arg, void  *trans);
43 /*
44         Clears the queue.
45
46         Calls list_clr on the underling list. This is not thread safe. Use queue_fin instead
47                 to wait for consumer threads to finish processing the data.
48 */
49
50 bool queue_enq(Queue *queue, void *dat);
51 /*
52         [Thread Safe]
53         Enqueues an element to the back of the queue.
54         Returns true if the enqueueing was successful (this is always the case if queue_fin
55                 has not been called)
56
57         Notifies waiting consumer threads.
58 */
59
60 bool queue_ppd(Queue *queue, void *dat);
61 /*
62         [Thread Safe]
63         Enqueues an element at the front of the queue.
64         Returns true if the enqueueing was successful (this is always the case if queue_fin
65                 has not been called)
66
67         Notifies waiting consumer threads.
68 */
69
70 void *queue_deq(Queue *queue, void *trans);
71 /*
72         [Thread Safe]
73         Dequeue an element.
74
75         If no element is in the queue, wait until there is one.
76         The (optional) transformer is called once an element is available and has been
77                 dequeued and while the queue mutex is still locked.
78
79         Note the the wait continues if the transformer returns NULL.
80 */
81
82 void queue_cnl(Queue *queue);
83 /*
84         [Thread Safe]
85         Cancels dequeueing.
86         Subsequent calls to queue_deq immediately return NULL.
87 */
88
89 void queue_fin(Queue *queue); // disallow enqueing, wait until consumption finished
90 /*
91         [Thread Safe]
92         Cancels enqueueing and waits for the queue to finish.
93         Subsequent calls to queue_enq have no effect and return false.
94
95         Before returning, this function waits for the queue to be empty.
96 */
97
98 #endif // _DRAGONSTD_QUEUE_H_