Major rewrite of the SilcThreadQueue API
[runtime.git] / lib / silcutil / silcthreadqueue.h
1 /*
2
3   silcthreadqueue.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2008 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 /****h* silcutil/Thread Queue Interface
21  *
22  * DESCRIPTION
23  *
24  * This interface provides asynchronous thread queues that can be used to
25  * pass messages and data between two or more threads.  Typically a thread
26  * would create the queue, push data into the queue and some other thread
27  * takes the data from the queue or blocks until more data is available
28  * in the queue.
29  *
30  * The queue itself can have one ore more pipes, allowing user to use one
31  * queue to pass different information in different pipes, if each pipe
32  * need to be dedicated to specific type of data.
33  *
34  * EXAMPLE
35  *
36  * Thread 1:
37  *
38  * // Create queue and push data into it
39  * SilcThreadQueue queue = silc_thread_queue_alloc(1, FALSE);
40  * silc_thread_queue_push(queue, 0, data, FALSE);
41  *
42  * Thread 2:
43  *
44  * // Connect to the queue
45  * silc_thread_queue_connect(queue);
46  *
47  * // Block here until data is available from the queue
48  * data = silc_thread_queue_pop(queue, 0, TRUE);
49  *
50  ***/
51
52 #ifndef SILCTHREADQUEUE_H
53 #define SILCTHREADQUEUE_H
54
55 /****s* silcutil/SilcThreadQueue
56  *
57  * NAME
58  *
59  *    typedef struct SilcThreadQueueStruct *SilcThreadQueue;
60  *
61  * DESCRIPTION
62  *
63  *    The thread queue context allocated by silc_thread_queue_alloc and
64  *    given as argument to all silc_thread_queue_* functions.
65  *
66  ***/
67 typedef struct SilcThreadQueueStruct *SilcThreadQueue;
68
69 /****f* silcutil/silc_thread_queue_alloc
70  *
71  * SYNOPSIS
72  *
73  *    SilcThreadQueue silc_thread_queue_alloc(int num_pipes, SilcBool fifo);
74  *
75  * DESCRIPTION
76  *
77  *    Allocates new thread queue context and returns it.  Returns NULL in
78  *    case of error and sets the silc_errno.  The returned context is
79  *    immediately ready to be used.  For a thread to be able to use the
80  *    queue it must first connect to it by calling silc_thread_queue_connect.
81  *    The thread that creates the queue automatically connects to the queue.
82  *
83  *    The 'num_pipes' specifies the number of pipes that exist in the queue.
84  *    If `num_pipes' is 0, the 0 is ignored and one pipe is created anyway.
85  *    By default, caller should create one pipe, unless more are needed.
86  *    The pipes are referenced by index.  First pipe has index 0, second
87  *    index 1, and so on.  The index is given as argument when pushing
88  *    and popping from the queue.
89  *
90  *    By default data popped from the queue is done in last-in-first-out
91  *    order; the most recently added data is popped first.  If `fifo' is
92  *    set to TRUE the order is first-in-first-out; the first added data is
93  *    popped first.
94  *
95  ***/
96 SilcThreadQueue silc_thread_queue_alloc(int num_pipes, SilcBool fifo);
97
98 /****f* silcutil/silc_thread_queue_connect
99  *
100  * SYNOPSIS
101  *
102  *    SilcBool silc_thread_queue_connect(SilcThreadQueue queue);
103  *
104  * DESCRIPTION
105  *
106  *    Connects current thread to the thread queue.  This function must
107  *    be called by each thread wanting to use the thread queue.  After the
108  *    thread is finished using the queue it must disconnect from the queue
109  *    by calling silc_thread_queue_disconnect.
110  *
111  ***/
112 void silc_thread_queue_connect(SilcThreadQueue queue);
113
114 /****f* silcutil/silc_thread_queue_disconnect
115  *
116  * SYNOPSIS
117  *
118  *    SilcBool silc_thread_queue_disconnect(SilcThreadQueue queue);
119  *
120  * DESCRIPTION
121  *
122  *    Disconnects the current thread from the thread queue.  This must be
123  *    called after the thread has finished using the thread queue.
124  *
125  *    When the last thread has disconnected from the queue the queue is
126  *    destroyed and this returns FALSE.  Otherwise this returns TRUE as
127  *    long as there are threads connected to the queue.
128  *
129  ***/
130 SilcBool silc_thread_queue_disconnect(SilcThreadQueue queue);
131
132 /****f* silcutil/silc_thread_queue_push
133  *
134  * SYNOPSIS
135  *
136  *    void silc_thread_queue_push(SilcThreadQueue queue, int pipe_index,
137  *                                void *data, SilcBool demux);
138  *
139  * DESCRIPTION
140  *
141  *    Pushes the `data' into the thread queue.  The data will become
142  *    immediately available in the queue for other threads.  The `pipe_index'
143  *    specifies the pipe to push the data into.  First pipe has index 0,
144  *    second has index 1, and so on.  If there is only one pipe the index
145  *    is always 0.
146  *
147  *    If the `demux' is TRUE this will perform demuxing; data pushed to one
148  *    pipe will be pushed to all pipes.  In this case the `pipe_index' is
149  *    ignored.  Each pipe will return the same data when popped.
150  *
151  ***/
152 void silc_thread_queue_push(SilcThreadQueue queue, int pipe_index, void *data,
153                             SilcBool demux);
154
155 /****f* silcutil/silc_thread_queue_pop
156  *
157  * SYNOPSIS
158  *
159  *    void *silc_thread_queue_pop(SilcThreadQueue queue, int pipe_index,
160  *                                SilcBool block);
161  *
162  * DESCRIPTION
163  *
164  *    Takes data from the queue and returns it.  If `block' is TRUE and
165  *    data is not available this will block until data becomes available.
166  *    If `block' is FALSE and data is not available this will return NULL.
167  *    If `block' is TRUE this will never return NULL.
168  *
169  *    The `pipe_index' specifies the pipe from which to pop the data.
170  *    First pipe has index 0, second has index 1, and so on.  If there is
171  *    only one pipe the index is always 0.
172  *
173  ***/
174 void *silc_thread_queue_pop(SilcThreadQueue queue, int pipe_index,
175                             SilcBool block);
176
177 /****f* silcutil/silc_thread_queue_timed_pop
178  *
179  * SYNOPSIS
180  *
181  *    void *silc_thread_queue_timed_pop(SilcThreadQueue queue,
182  *                                      int pipe_index, int timeout_msec);
183  *
184  * DESCRIPTION
185  *
186  *    Takes data from the thread queue or waits at most `timeout_msec'
187  *    milliseconds for the data to arrive.  If data is not available when
188  *    the timeout occurrs this returns NULL.
189  *
190  *    The `pipe_index' specifies the pipe from which to pop the data.
191  *    First pipe has index 0, second has index 1, and so on.  If there is
192  *    only one pipe the index is always 0.
193  *
194  ***/
195 void *silc_thread_queue_timed_pop(SilcThreadQueue queue, int pipe_index,
196                                   int timeout_msec);
197
198 /****f* silcutil/silc_thread_queue_pop_list
199  *
200  * SYNOPSIS
201  *
202  *    SilcDList silc_thread_queue_pop_list(SilcThreadQueue queue,
203  *                                         int pipe_index, SilcBool block);
204  *
205  * DESCRIPTION
206  *
207  *    Takes everything from the queue and returns the data in a list.  The
208  *    caller must free the returned list with silc_dlist_uninit.  If the
209  *    `block' is FALSE this will never block but will return the queue
210  *    immediately.  If `block' is TRUE this will block if the queue is
211  *    empty.
212  *
213  *    The `pipe_index' specifies the pipe from which to pop the list.
214  *    First pipe has index 0, second has index 1, and so on.  If there is
215  *    only one pipe the index is always 0.
216  *
217  ***/
218 SilcDList silc_thread_queue_pop_list(SilcThreadQueue queue, int pipe_index,
219                                      SilcBool block);
220
221 #endif /* SILCTHREADQUEUE_H */