diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2015-06-14 00:24:57 +1000 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2015-06-14 00:25:24 +1000 |
commit | 5cdc505e7ec54d144c10f12a5453b7793b891e1e (patch) | |
tree | ea2d44b5b5f1c77522d71fc9fedde6ffc91406a3 | |
parent | d448f12d07c5b65d5db29f207de3178490f8360d (diff) |
lqueue: Allow a queueu to be initialized from an existing back element
There are occasional cases where you might construct a valid queue, and
retain a direct pointer to the back element, but not the struct lqueue
used to build it.
This patch adds a new lqueue_init_from_back() macro to reconstruct a valid
struct lqueue from the element pointer for cases like this.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r-- | ccan/lqueue/lqueue.h | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/ccan/lqueue/lqueue.h b/ccan/lqueue/lqueue.h index 15d242ef..1af5847f 100644 --- a/ccan/lqueue/lqueue.h +++ b/ccan/lqueue/lqueue.h @@ -51,6 +51,33 @@ struct lqueue { struct lqueue name = { NULL, } /** + * lqueue_init_from_back - initialize a queue with a specific back element + * @s: the lqueue to initialize + * @e: pointer to the back element of the new queue + * @member: member of the element containing the lqueue_link + * + * USE WITH CAUTION: This is for handling unusual cases where you have + * a pointer to an element in a previously constructed queue but can't + * conveniently pass around a normal struct lqueue. Usually you + * should use lqueue_init(). + * + * Example: + * LQUEUE(queue1); + * struct lqueue queue2; + * struct element { + * int value; + * struct lqueue_link link; + * } el; + * + * lqueue_enqueue(&queue1, &el, link); + * + * lqueue_init_from_back(&queue2, + * lqueue_back(&queue1, struct element, link), link); + */ +#define lqueue_init_from_back(s, e, member) \ + (lqueue_init_((s), &(e)->member)) + +/** * lqueue_init - initialize a queue * @h: the lqueue to set to an empty queue * @@ -58,9 +85,11 @@ struct lqueue { * struct lqueue *qp = malloc(sizeof(*qp)); * lqueue_init(qp); */ -static inline void lqueue_init(struct lqueue *q) +#define lqueue_init(s) \ + (lqueue_init_((s), NULL)) +static inline void lqueue_init_(struct lqueue *q, struct lqueue_link *back) { - q->back = NULL; + q->back = back; } /** |