5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2008 Pekka Riikonen
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.
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.
20 /****h* silcutil/Thread Queue Interface
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
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.
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);
44 * // Connect to the queue
45 * silc_thread_queue_connect(queue);
47 * // Block here until data is available from the queue
48 * data = silc_thread_queue_pop(queue, 0, TRUE);
52 #ifndef SILCTHREADQUEUE_H
53 #define SILCTHREADQUEUE_H
55 /****s* silcutil/SilcThreadQueue
59 * typedef struct SilcThreadQueueStruct *SilcThreadQueue;
63 * The thread queue context allocated by silc_thread_queue_alloc and
64 * given as argument to all silc_thread_queue_* functions.
67 typedef struct SilcThreadQueueStruct *SilcThreadQueue;
69 /****f* silcutil/silc_thread_queue_alloc
73 * SilcThreadQueue silc_thread_queue_alloc(int num_pipes, SilcBool fifo);
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.
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.
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
96 SilcThreadQueue silc_thread_queue_alloc(int num_pipes, SilcBool fifo);
98 /****f* silcutil/silc_thread_queue_connect
102 * SilcBool silc_thread_queue_connect(SilcThreadQueue queue);
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.
112 void silc_thread_queue_connect(SilcThreadQueue queue);
114 /****f* silcutil/silc_thread_queue_disconnect
118 * SilcBool silc_thread_queue_disconnect(SilcThreadQueue queue);
122 * Disconnects the current thread from the thread queue. This must be
123 * called after the thread has finished using the thread queue.
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.
130 SilcBool silc_thread_queue_disconnect(SilcThreadQueue queue);
132 /****f* silcutil/silc_thread_queue_push
136 * void silc_thread_queue_push(SilcThreadQueue queue, int pipe_index,
137 * void *data, SilcBool demux);
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
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.
152 void silc_thread_queue_push(SilcThreadQueue queue, int pipe_index, void *data,
155 /****f* silcutil/silc_thread_queue_pop
159 * void *silc_thread_queue_pop(SilcThreadQueue queue, int pipe_index,
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.
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.
174 void *silc_thread_queue_pop(SilcThreadQueue queue, int pipe_index,
177 /****f* silcutil/silc_thread_queue_timed_pop
181 * void *silc_thread_queue_timed_pop(SilcThreadQueue queue,
182 * int pipe_index, int timeout_msec);
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.
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.
195 void *silc_thread_queue_timed_pop(SilcThreadQueue queue, int pipe_index,
198 /****f* silcutil/silc_thread_queue_pop_list
202 * SilcDList silc_thread_queue_pop_list(SilcThreadQueue queue,
203 * int pipe_index, SilcBool block);
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
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.
218 SilcDList silc_thread_queue_pop_list(SilcThreadQueue queue, int pipe_index,
221 #endif /* SILCTHREADQUEUE_H */