Harald Welte | e4cd267 | 2019-08-06 19:56:16 +0200 | [diff] [blame] | 1 | #pragma once |
| 2 | |
| 3 | #include <osmocom/core/linuxlist.h> |
| 4 | #include <osmocom/core/select.h> |
| 5 | #include <pthread.h> |
| 6 | |
| 7 | /*! \defgroup osmo_it_q Inter-Thread Queue |
| 8 | * @{ |
| 9 | * \file osmo_it_q.h */ |
| 10 | |
| 11 | /*! One instance of an inter-thread queue. The user can use this to queue messages |
| 12 | * between different threads. The enqueue operation is non-blocking (but of course |
| 13 | * grabs a mutex for the actual list operations to safeguard against races). The |
| 14 | * receiving thread is woken up by an event_fd which can be registered in the libosmocore |
| 15 | * select loop handling. */ |
| 16 | struct osmo_it_q { |
| 17 | /* entry in global list of message queues */ |
| 18 | struct llist_head entry; |
| 19 | |
| 20 | /* the actual list of user structs. HEAD: first in queue; TAIL: last in queue */ |
| 21 | struct llist_head list; |
| 22 | /* A pthread mutex to safeguard accesses to the queue. No rwlock as we always write. */ |
| 23 | pthread_mutex_t mutex; |
| 24 | /* Current count of messages in the queue */ |
| 25 | unsigned int current_length; |
| 26 | /* osmo-fd wrapped eventfd */ |
| 27 | struct osmo_fd event_ofd; |
| 28 | |
| 29 | /* a user-defined name for this queue */ |
| 30 | const char *name; |
| 31 | /* maximum permitted length of queue */ |
| 32 | unsigned int max_length; |
| 33 | /* read call-back, called for each de-queued message */ |
| 34 | void (*read_cb)(struct osmo_it_q *q, struct llist_head *item); |
| 35 | /* opaque data pointer passed through to call-back function */ |
| 36 | void *data; |
| 37 | }; |
| 38 | |
| 39 | struct osmo_it_q *osmo_it_q_by_name(const char *name); |
| 40 | |
| 41 | int _osmo_it_q_enqueue(struct osmo_it_q *queue, struct llist_head *item); |
| 42 | #define osmo_it_q_enqueue(queue, item, member) \ |
| 43 | _osmo_it_q_enqueue(queue, &(item)->member) |
| 44 | |
| 45 | struct llist_head *_osmo_it_q_dequeue(struct osmo_it_q *queue); |
| 46 | #define osmo_it_q_dequeue(queue, item, member) do { \ |
| 47 | struct llist_head *l = _osmo_it_q_dequeue(queue); \ |
| 48 | if (!l) \ |
| 49 | *item = NULL; \ |
| 50 | else \ |
| 51 | *item = llist_entry(l, typeof(**item), member); \ |
| 52 | } while (0) |
| 53 | |
| 54 | |
| 55 | struct osmo_it_q *osmo_it_q_alloc(void *ctx, const char *name, unsigned int max_length, |
| 56 | |
| 57 | void (*read_cb)(struct osmo_it_q *q, struct llist_head *item), |
| 58 | void *data); |
| 59 | void osmo_it_q_destroy(struct osmo_it_q *q); |
| 60 | void osmo_it_q_flush(struct osmo_it_q *q); |
| 61 | |
| 62 | /*! @} */ |