Synchronized queue
This queue may be used for implementation of producer-consumer models.
While producer creates objects and puts them onto queue via squeue_push(),
consumer (one or many) waits for it objects in squeue_pop() and awakes
if object was put on queue.
Since there is no way to interrupt consumers, you may put NULL onto
queue and handle this situation in consumer code or call squeue_destroy()
Functions
squeue_init
public
Initialize synchronized queue
ARGUMENTS
-
sq - - queue
-
name - - name of queue (for debugging purposes)
LIBEXPORT void squeue_init(squeue_t* sq, const char* namefmt, ...)
squeue_pop
public
Extract element from synchronized queue.
If no elements on queue, blocks until squeue_push will add an element.
May be called from multiple threads simultaneously, thread selected
in cv_notify_one wins (undetermined for most platforms).
ARGUMENTS
-
sq - queue
RETURN VALUES
element or NULL if squeue is destroyed
LIBEXPORT void* squeue_pop(squeue_t* sq)
squeue_push
public
Put an element on synchronized queue.
ARGUMENTS
-
object - element
LIBEXPORT void squeue_push(squeue_t* sq, void* object)
squeue_destroy
public
Destroy all elements in queue and queue itself. Also notifies squeue_pop
Doesn't deallocate squeue_t
ARGUMENTS
-
sq - synchronized queue to destroy
-
free - helper to destroy element's data
NOTES
squeue_destroy() will notify consumer but doesn't guarantee that it will leave squeue_pop(). You need to check this on your own. It could be easily done by joining consumer thread.
LIBEXPORT void squeue_destroy(squeue_t* sq, void (*el_free)(void* obj))
Types
typedef struct squeue_el
typedef struct squeue_el { struct squeue_el* s_next; void* s_data; } squeue_el_t;
typedef struct squeue
typedef struct squeue { thread_mutex_t sq_mutex; thread_cv_t sq_cv; squeue_el_t* sq_head; squeue_el_t* sq_tail; char sq_name[SQUEUENAMELEN]; boolean_t sq_is_destroyed; } squeue_t;