L4Re/departure

libext2fs/include/libblkid/blkid/list.h

617:2733e5770ee9
9 months ago Paul Boddie Made the run command wait for completion, introducing the spawn command to run programs in the background. Introduced conveniences for waiting for the last job to be initiated and for piping from the last job, also subscribing to signals from pipe-supplying jobs so that they may be transparently removed from the job list upon completion. Augmented the job listing with the "+" notation familiar from Unix. Prevented new jobs from being started when no job slots are available.
     1 #if !defined(_BLKID_LIST_H) && !defined(LIST_HEAD_INIT)     2 #define _BLKID_LIST_H     3      4 #ifdef __cplusplus     5 extern "C" {     6 #endif     7      8 #ifdef HAVE_INTTYPES_H     9 #include <inttypes.h>    10 #else    11 #ifdef HAVE_STDINT_H    12 #include <stdint.h>    13 #endif    14 #endif    15     16 #ifdef __GNUC__    17 #define _INLINE_ static __inline__    18 #else                         /* For Watcom C */    19 #define _INLINE_ static inline    20 #endif    21     22 /*    23  * Simple doubly linked list implementation.    24  *    25  * Some of the internal functions ("__xxx") are useful when    26  * manipulating whole lists rather than single entries, as    27  * sometimes we already know the next/prev entries and we can    28  * generate better code by using them directly rather than    29  * using the generic single-entry routines.    30  */    31     32 struct list_head {    33 	struct list_head *next, *prev;    34 };    35     36 #define LIST_HEAD_INIT(name) { &(name), &(name) }    37     38 #define INIT_LIST_HEAD(ptr) do { \    39 	(ptr)->next = (ptr); (ptr)->prev = (ptr); \    40 } while (0)    41     42 /*    43  * Insert a new entry between two known consecutive entries.    44  *    45  * This is only for internal list manipulation where we know    46  * the prev/next entries already!    47  */    48 _INLINE_ void __list_add(struct list_head * add,    49 	struct list_head * prev,    50 	struct list_head * next)    51 {    52 	next->prev = add;    53 	add->next = next;    54 	add->prev = prev;    55 	prev->next = add;    56 }    57     58 /**    59  * list_add - add a new entry    60  * @add:	new entry to be added    61  * @head:	list head to add it after    62  *    63  * Insert a new entry after the specified head.    64  * This is good for implementing stacks.    65  */    66 _INLINE_ void list_add(struct list_head *add, struct list_head *head)    67 {    68 	__list_add(add, head, head->next);    69 }    70     71 /**    72  * list_add_tail - add a new entry    73  * @add:	new entry to be added    74  * @head:	list head to add it before    75  *    76  * Insert a new entry before the specified head.    77  * This is useful for implementing queues.    78  */    79 _INLINE_ void list_add_tail(struct list_head *add, struct list_head *head)    80 {    81 	__list_add(add, head->prev, head);    82 }    83     84 /*    85  * Delete a list entry by making the prev/next entries    86  * point to each other.    87  *    88  * This is only for internal list manipulation where we know    89  * the prev/next entries already!    90  */    91 _INLINE_ void __list_del(struct list_head * prev,    92 				  struct list_head * next)    93 {    94 	next->prev = prev;    95 	prev->next = next;    96 }    97     98 /**    99  * list_del - deletes entry from list.   100  * @entry:	the element to delete from the list.   101  *   102  * list_empty() on @entry does not return true after this, @entry is   103  * in an undefined state.   104  */   105 _INLINE_ void list_del(struct list_head *entry)   106 {   107 	__list_del(entry->prev, entry->next);   108 }   109    110 /**   111  * list_del_init - deletes entry from list and reinitialize it.   112  * @entry:	the element to delete from the list.   113  */   114 _INLINE_ void list_del_init(struct list_head *entry)   115 {   116 	__list_del(entry->prev, entry->next);   117 	INIT_LIST_HEAD(entry);   118 }   119    120 /**   121  * list_empty - tests whether a list is empty   122  * @head:	the list to test.   123  */   124 _INLINE_ int list_empty(struct list_head *head)   125 {   126 	return head->next == head;   127 }   128    129 /**   130  * list_splice - join two lists   131  * @list:	the new list to add.   132  * @head:	the place to add it in the first list.   133  */   134 _INLINE_ void list_splice(struct list_head *list, struct list_head *head)   135 {   136 	struct list_head *first = list->next;   137    138 	if (first != list) {   139 		struct list_head *last = list->prev;   140 		struct list_head *at = head->next;   141    142 		first->prev = head;   143 		head->next = first;   144    145 		last->next = at;   146 		at->prev = last;   147 	}   148 }   149    150 /**   151  * list_entry - get the struct for this entry   152  * @ptr:	the &struct list_head pointer.   153  * @type:	the type of the struct this is embedded in.   154  * @member:	the name of the list_struct within the struct.   155  */   156 #define list_entry(ptr, type, member) \   157 	((type *)((char *)(ptr)-(unsigned long)(intptr_t)(&((type *)0)->member)))   158    159 /**   160  * list_for_each - iterate over elements in a list   161  * @pos:	the &struct list_head to use as a loop counter.   162  * @head:	the head for your list.   163  */   164 #define list_for_each(pos, head) \   165 	for (pos = (head)->next; pos != (head); pos = pos->next)   166    167 /**   168  * list_for_each_safe - iterate over elements in a list, but don't dereference   169  *                      pos after the body is done (in case it is freed)   170  * @pos:	the &struct list_head to use as a loop counter.   171  * @pnext:	the &struct list_head to use as a pointer to the next item.   172  * @head:	the head for your list (not included in iteration).   173  */   174 #define list_for_each_safe(pos, pnext, head) \   175 	for (pos = (head)->next, pnext = pos->next; pos != (head); \   176 	     pos = pnext, pnext = pos->next)   177    178 #undef _INLINE_   179    180 #ifdef __cplusplus   181 }   182 #endif   183    184 #endif /* _BLKID_LIST_H */