A singly-linked tail queue is headed by a structure defined by the STAILQ_HEAD macro. This structure contains a pair of pointers, one to the first element in the tail queue and the other to the last element in the tail queue. The elements are singly linked for minimum space and pointer manipulation overhead at the expense of 0(n) removal for arbitrary elements. New elements can be added to the tail queue after an existing element, at the head of the tail queue, or at the end of the tail queue. A STAILQ_HEAD structure is declared as follows:
STAILQ_HEAD(HEADNAME, TYPE) head;
where HEADNAME is the name of the structure to be defined, and TYPE is the type of the elements to be linked into the tail queu. A pointer to the head of the tail queue can be later be declared as follows:
struct HEADNAME *headp;
SINGLY-LINKED TAIL QUEUE EXAMPLE
STAILQ_HEAD(stailhead, entry) head = STAILQ_HEAD_INITIALIZER(head);
struct stailhead *headp; /* Singly-linked tail queue head*/
struct entry {
...
STAILQ_ENTRY(entry); entries; /*Tail queue.*/
...
} *n1, *n2, *n3, *np;
STAILQ_INIT(&head); /*Initialize the queue*/
n1 = malloc(sizeof(struct entry)); /*Insert at the head*/
STAILQ_INSERT_HEAD(&head, n1, entries);
n1 = malloc(sizeof(struct entry));
STAILQ_INSERT_TAIL(&head, n1, entries);
n2 = malloc(sizeof(struct entry));
STAILQ_INSERT_AFTER(&head, n1, n2, entries); /*Insert after ...*/
STAILQ_REMOVE(&head, n2, entry, entries);
free(n2);
n3 = STAILQ_FIRST(&head);
STAILQ_REMOVE_HEAD(&head, entries);
free(n3);
/* Forward traversal. */
STAILQ_FOREACH(np, &head, entries)
np-> ...
/* Safe forward traversal. */
STAILQ_FOREACH_SAFE(np, &head, entries, np_temp) {
np->do_stuff();
...
STAILQ_REMOVE(&head, np, entry, entries);
free(np);
}
/* TailQ Deletion. */
while (!STAILQ_EMPTY(&head)) {
n1 = STAILQ_FIRST(&head);
STAILQ_REMOVE_HEAD(&head, entries);
free(n1);
}
/* Faster TailQ Deletion. */
n1 = STAILQ_FIRST(&head);
while (n1 != NULL) {
n2 = STAILQ_NEXT(n1, entries);
free(n1);
n1 = n2;
}
STAILQ_INIT(&head);