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

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

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

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

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;