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