summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2015-06-14 00:24:57 +1000
committerDavid Gibson <david@gibson.dropbear.id.au>2015-06-14 00:25:24 +1000
commit5cdc505e7ec54d144c10f12a5453b7793b891e1e (patch)
treeea2d44b5b5f1c77522d71fc9fedde6ffc91406a3
parentd448f12d07c5b65d5db29f207de3178490f8360d (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.h33
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;
}
/**