summaryrefslogtreecommitdiffstats
path: root/src/asyncq.h
blob: 5d26283bd47c736b4e0cf7ac3abe5f4711289c1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#ifndef foosydneyasynchfoo
#define foosydneyasynchfoo

#include "llist.h"
#include "mutex.h"

typedef struct sa_asyncq sa_asyncq_t;
typedef struct sa_asyncq_item sa_asyncq_item_t;

struct sa_asyncq_item {
    SA_LLIST_ITEM(sa_asyncq_item_t, items);
};

#define SA_ASYNCQ_ITEM_DATA(x) ((void*) ((uint8_t*) (x) + SA_ALIGN(sizeof(sa_asyncq_item_t))))

struct sa_asyncq {
    sa_mutex_t *mutex;

    SA_LLIST_HEAD(sa_asyncq_item_t, items);
    SA_LLIST_HEAD(sa_asyncq_item_t, unused);

    sa_asyncq_item_t *last;

    size_t item_size;
};

/* Implements a simple asynchronous queue for
 * inter-thread-communication. To reading side can act in a wait-free
 * fashion (though not lock-free). Should only be used together with a
 * non-sychrnoized backing buffer such as sa_bufferq. */

int sa_asyncq_init(sa_asyncq_t *a, size_t item_size);

void sa_asyncq_done(sa_asyncq_t *a);

/* Allocate a free queue item */
sa_asyncq_item_t *sa_asyncq_get(sa_asyncq_t *a);

/* Give the queue item back to the queue */
void sa_asyncq_recycle(sa_asyncq_t *a);

/* Push a previously allocated entry into the queue */
void sa_asyncq_push(sa_asyncq_t *a, sa_asyncq_item_t *i);

/* Pop an entry from the queue */
sa_asyncq_item_t* sa_asyncq_pop(sa_asyncq_t *a, int wait);


#endif