00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef _DB_QUEUE_H_
00038 #define _DB_QUEUE_H_
00039
00040 #if defined(__cplusplus)
00041 extern "C" {
00042 #endif
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 #undef LIST_EMPTY
00119 #undef LIST_ENTRY
00120 #undef LIST_FIRST
00121 #undef LIST_FOREACH
00122 #undef LIST_HEAD
00123 #undef LIST_HEAD_INITIALIZER
00124 #undef LIST_INIT
00125 #undef LIST_INSERT_AFTER
00126 #undef LIST_INSERT_BEFORE
00127 #undef LIST_INSERT_HEAD
00128 #undef LIST_NEXT
00129 #undef LIST_REMOVE
00130 #undef QMD_TRACE_ELEM
00131 #undef QMD_TRACE_HEAD
00132 #undef QUEUE_MACRO_DEBUG
00133 #undef SLIST_EMPTY
00134 #undef SLIST_ENTRY
00135 #undef SLIST_FIRST
00136 #undef SLIST_FOREACH
00137 #undef SLIST_FOREACH_PREVPTR
00138 #undef SLIST_HEAD
00139 #undef SLIST_HEAD_INITIALIZER
00140 #undef SLIST_INIT
00141 #undef SLIST_INSERT_AFTER
00142 #undef SLIST_INSERT_HEAD
00143 #undef SLIST_NEXT
00144 #undef SLIST_REMOVE
00145 #undef SLIST_REMOVE_HEAD
00146 #undef STAILQ_CONCAT
00147 #undef STAILQ_EMPTY
00148 #undef STAILQ_ENTRY
00149 #undef STAILQ_FIRST
00150 #undef STAILQ_FOREACH
00151 #undef STAILQ_HEAD
00152 #undef STAILQ_HEAD_INITIALIZER
00153 #undef STAILQ_INIT
00154 #undef STAILQ_INSERT_AFTER
00155 #undef STAILQ_INSERT_HEAD
00156 #undef STAILQ_INSERT_TAIL
00157 #undef STAILQ_LAST
00158 #undef STAILQ_NEXT
00159 #undef STAILQ_REMOVE
00160 #undef STAILQ_REMOVE_HEAD
00161 #undef STAILQ_REMOVE_HEAD_UNTIL
00162 #undef TAILQ_CONCAT
00163 #undef TAILQ_EMPTY
00164 #undef TAILQ_ENTRY
00165 #undef TAILQ_FIRST
00166 #undef TAILQ_FOREACH
00167 #undef TAILQ_FOREACH_REVERSE
00168 #undef TAILQ_HEAD
00169 #undef TAILQ_HEAD_INITIALIZER
00170 #undef TAILQ_INIT
00171 #undef TAILQ_INSERT_AFTER
00172 #undef TAILQ_INSERT_BEFORE
00173 #undef TAILQ_INSERT_HEAD
00174 #undef TAILQ_INSERT_TAIL
00175 #undef TAILQ_LAST
00176 #undef TAILQ_NEXT
00177 #undef TAILQ_PREV
00178 #undef TAILQ_REMOVE
00179 #undef TRACEBUF
00180 #undef TRASHIT
00181
00182 #define QUEUE_MACRO_DEBUG 0
00183 #if QUEUE_MACRO_DEBUG
00184
00185 struct qm_trace {
00186 char * lastfile;
00187 int lastline;
00188 char * prevfile;
00189 int prevline;
00190 };
00191
00192 #define TRACEBUF struct qm_trace trace;
00193 #define TRASHIT(x) do {(x) = (void *)-1;} while (0)
00194
00195 #define QMD_TRACE_HEAD(head) do { \
00196 (head)->trace.prevline = (head)->trace.lastline; \
00197 (head)->trace.prevfile = (head)->trace.lastfile; \
00198 (head)->trace.lastline = __LINE__; \
00199 (head)->trace.lastfile = __FILE__; \
00200 } while (0)
00201
00202 #define QMD_TRACE_ELEM(elem) do { \
00203 (elem)->trace.prevline = (elem)->trace.lastline; \
00204 (elem)->trace.prevfile = (elem)->trace.lastfile; \
00205 (elem)->trace.lastline = __LINE__; \
00206 (elem)->trace.lastfile = __FILE__; \
00207 } while (0)
00208
00209 #else
00210 #define QMD_TRACE_ELEM(elem)
00211 #define QMD_TRACE_HEAD(head)
00212 #define TRACEBUF
00213 #define TRASHIT(x)
00214 #endif
00215
00216
00217
00218
00219 #define SLIST_HEAD(name, type) \
00220 struct name { \
00221 struct type *slh_first; \
00222 }
00223
00224 #define SLIST_HEAD_INITIALIZER(head) \
00225 { NULL }
00226
00227 #define SLIST_ENTRY(type) \
00228 struct { \
00229 struct type *sle_next; \
00230 }
00231
00232
00233
00234
00235 #define SLIST_EMPTY(head) ((head)->slh_first == NULL)
00236
00237 #define SLIST_FIRST(head) ((head)->slh_first)
00238
00239 #define SLIST_FOREACH(var, head, field) \
00240 for ((var) = SLIST_FIRST((head)); \
00241 (var); \
00242 (var) = SLIST_NEXT((var), field))
00243
00244 #define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
00245 for ((varp) = &SLIST_FIRST((head)); \
00246 ((var) = *(varp)) != NULL; \
00247 (varp) = &SLIST_NEXT((var), field))
00248
00249 #define SLIST_INIT(head) do { \
00250 SLIST_FIRST((head)) = NULL; \
00251 } while (0)
00252
00253 #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
00254 SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
00255 SLIST_NEXT((slistelm), field) = (elm); \
00256 } while (0)
00257
00258 #define SLIST_INSERT_HEAD(head, elm, field) do { \
00259 SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
00260 SLIST_FIRST((head)) = (elm); \
00261 } while (0)
00262
00263 #define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
00264
00265 #define SLIST_REMOVE(head, elm, type, field) do { \
00266 if (SLIST_FIRST((head)) == (elm)) { \
00267 SLIST_REMOVE_HEAD((head), field); \
00268 } \
00269 else { \
00270 struct type *curelm = SLIST_FIRST((head)); \
00271 while (SLIST_NEXT(curelm, field) != (elm)) \
00272 curelm = SLIST_NEXT(curelm, field); \
00273 SLIST_NEXT(curelm, field) = \
00274 SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
00275 } \
00276 } while (0)
00277
00278 #define SLIST_REMOVE_HEAD(head, field) do { \
00279 SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
00280 } while (0)
00281
00282
00283
00284
00285 #define STAILQ_HEAD(name, type) \
00286 struct name { \
00287 struct type *stqh_first; \
00288 struct type **stqh_last; \
00289 }
00290
00291 #define STAILQ_HEAD_INITIALIZER(head) \
00292 { NULL, &(head).stqh_first }
00293
00294 #define STAILQ_ENTRY(type) \
00295 struct { \
00296 struct type *stqe_next; \
00297 }
00298
00299
00300
00301
00302 #define STAILQ_CONCAT(head1, head2) do { \
00303 if (!STAILQ_EMPTY((head2))) { \
00304 *(head1)->stqh_last = (head2)->stqh_first; \
00305 (head1)->stqh_last = (head2)->stqh_last; \
00306 STAILQ_INIT((head2)); \
00307 } \
00308 } while (0)
00309
00310 #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
00311
00312 #define STAILQ_FIRST(head) ((head)->stqh_first)
00313
00314 #define STAILQ_FOREACH(var, head, field) \
00315 for ((var) = STAILQ_FIRST((head)); \
00316 (var); \
00317 (var) = STAILQ_NEXT((var), field))
00318
00319 #define STAILQ_INIT(head) do { \
00320 STAILQ_FIRST((head)) = NULL; \
00321 (head)->stqh_last = &STAILQ_FIRST((head)); \
00322 } while (0)
00323
00324 #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
00325 if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
00326 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
00327 STAILQ_NEXT((tqelm), field) = (elm); \
00328 } while (0)
00329
00330 #define STAILQ_INSERT_HEAD(head, elm, field) do { \
00331 if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
00332 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
00333 STAILQ_FIRST((head)) = (elm); \
00334 } while (0)
00335
00336 #define STAILQ_INSERT_TAIL(head, elm, field) do { \
00337 STAILQ_NEXT((elm), field) = NULL; \
00338 *(head)->stqh_last = (elm); \
00339 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
00340 } while (0)
00341
00342 #define STAILQ_LAST(head, type, field) \
00343 (STAILQ_EMPTY((head)) ? \
00344 NULL : \
00345 ((struct type *) \
00346 ((char *)((head)->stqh_last) - __offsetof(struct type, field))))
00347
00348 #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
00349
00350 #define STAILQ_REMOVE(head, elm, type, field) do { \
00351 if (STAILQ_FIRST((head)) == (elm)) { \
00352 STAILQ_REMOVE_HEAD((head), field); \
00353 } \
00354 else { \
00355 struct type *curelm = STAILQ_FIRST((head)); \
00356 while (STAILQ_NEXT(curelm, field) != (elm)) \
00357 curelm = STAILQ_NEXT(curelm, field); \
00358 if ((STAILQ_NEXT(curelm, field) = \
00359 STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
00360 (head)->stqh_last = &STAILQ_NEXT((curelm), field);\
00361 } \
00362 } while (0)
00363
00364 #define STAILQ_REMOVE_HEAD(head, field) do { \
00365 if ((STAILQ_FIRST((head)) = \
00366 STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
00367 (head)->stqh_last = &STAILQ_FIRST((head)); \
00368 } while (0)
00369
00370 #define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
00371 if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
00372 (head)->stqh_last = &STAILQ_FIRST((head)); \
00373 } while (0)
00374
00375
00376
00377
00378 #define LIST_HEAD(name, type) \
00379 struct name { \
00380 struct type *lh_first; \
00381 }
00382
00383 #define LIST_HEAD_INITIALIZER(head) \
00384 { NULL }
00385
00386 #define LIST_ENTRY(type) \
00387 struct { \
00388 struct type *le_next; \
00389 struct type **le_prev; \
00390 }
00391
00392
00393
00394
00395
00396 #define LIST_EMPTY(head) ((head)->lh_first == NULL)
00397
00398 #define LIST_FIRST(head) ((head)->lh_first)
00399
00400 #define LIST_FOREACH(var, head, field) \
00401 for ((var) = LIST_FIRST((head)); \
00402 (var); \
00403 (var) = LIST_NEXT((var), field))
00404
00405 #define LIST_INIT(head) do { \
00406 LIST_FIRST((head)) = NULL; \
00407 } while (0)
00408
00409 #define LIST_INSERT_AFTER(listelm, elm, field) do { \
00410 if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
00411 LIST_NEXT((listelm), field)->field.le_prev = \
00412 &LIST_NEXT((elm), field); \
00413 LIST_NEXT((listelm), field) = (elm); \
00414 (elm)->field.le_prev = &LIST_NEXT((listelm), field); \
00415 } while (0)
00416
00417 #define LIST_INSERT_BEFORE(listelm, elm, field) do { \
00418 (elm)->field.le_prev = (listelm)->field.le_prev; \
00419 LIST_NEXT((elm), field) = (listelm); \
00420 *(listelm)->field.le_prev = (elm); \
00421 (listelm)->field.le_prev = &LIST_NEXT((elm), field); \
00422 } while (0)
00423
00424 #define LIST_INSERT_HEAD(head, elm, field) do { \
00425 if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
00426 LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
00427 LIST_FIRST((head)) = (elm); \
00428 (elm)->field.le_prev = &LIST_FIRST((head)); \
00429 } while (0)
00430
00431 #define LIST_NEXT(elm, field) ((elm)->field.le_next)
00432
00433 #define LIST_REMOVE(elm, field) do { \
00434 if (LIST_NEXT((elm), field) != NULL) \
00435 LIST_NEXT((elm), field)->field.le_prev = \
00436 (elm)->field.le_prev; \
00437 *(elm)->field.le_prev = LIST_NEXT((elm), field); \
00438 } while (0)
00439
00440
00441
00442
00443 #define TAILQ_HEAD(name, type) \
00444 struct name { \
00445 struct type *tqh_first; \
00446 struct type **tqh_last; \
00447 TRACEBUF \
00448 }
00449
00450 #define TAILQ_HEAD_INITIALIZER(head) \
00451 { NULL, &(head).tqh_first }
00452
00453 #define TAILQ_ENTRY(type) \
00454 struct { \
00455 struct type *tqe_next; \
00456 struct type **tqe_prev; \
00457 TRACEBUF \
00458 }
00459
00460
00461
00462
00463 #define TAILQ_CONCAT(head1, head2, field) do { \
00464 if (!TAILQ_EMPTY(head2)) { \
00465 *(head1)->tqh_last = (head2)->tqh_first; \
00466 (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
00467 (head1)->tqh_last = (head2)->tqh_last; \
00468 TAILQ_INIT((head2)); \
00469 QMD_TRACE_HEAD(head); \
00470 QMD_TRACE_HEAD(head2); \
00471 } \
00472 } while (0)
00473
00474 #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
00475
00476 #define TAILQ_FIRST(head) ((head)->tqh_first)
00477
00478 #define TAILQ_FOREACH(var, head, field) \
00479 for ((var) = TAILQ_FIRST((head)); \
00480 (var); \
00481 (var) = TAILQ_NEXT((var), field))
00482
00483 #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
00484 for ((var) = TAILQ_LAST((head), headname); \
00485 (var); \
00486 (var) = TAILQ_PREV((var), headname, field))
00487
00488 #define TAILQ_INIT(head) do { \
00489 TAILQ_FIRST((head)) = NULL; \
00490 (head)->tqh_last = &TAILQ_FIRST((head)); \
00491 QMD_TRACE_HEAD(head); \
00492 } while (0)
00493
00494 #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
00495 if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
00496 TAILQ_NEXT((elm), field)->field.tqe_prev = \
00497 &TAILQ_NEXT((elm), field); \
00498 else { \
00499 (head)->tqh_last = &TAILQ_NEXT((elm), field); \
00500 QMD_TRACE_HEAD(head); \
00501 } \
00502 TAILQ_NEXT((listelm), field) = (elm); \
00503 (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
00504 QMD_TRACE_ELEM(&(elm)->field); \
00505 QMD_TRACE_ELEM(&listelm->field); \
00506 } while (0)
00507
00508 #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
00509 (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
00510 TAILQ_NEXT((elm), field) = (listelm); \
00511 *(listelm)->field.tqe_prev = (elm); \
00512 (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
00513 QMD_TRACE_ELEM(&(elm)->field); \
00514 QMD_TRACE_ELEM(&listelm->field); \
00515 } while (0)
00516
00517 #define TAILQ_INSERT_HEAD(head, elm, field) do { \
00518 if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
00519 TAILQ_FIRST((head))->field.tqe_prev = \
00520 &TAILQ_NEXT((elm), field); \
00521 else \
00522 (head)->tqh_last = &TAILQ_NEXT((elm), field); \
00523 TAILQ_FIRST((head)) = (elm); \
00524 (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
00525 QMD_TRACE_HEAD(head); \
00526 QMD_TRACE_ELEM(&(elm)->field); \
00527 } while (0)
00528
00529 #define TAILQ_INSERT_TAIL(head, elm, field) do { \
00530 TAILQ_NEXT((elm), field) = NULL; \
00531 (elm)->field.tqe_prev = (head)->tqh_last; \
00532 *(head)->tqh_last = (elm); \
00533 (head)->tqh_last = &TAILQ_NEXT((elm), field); \
00534 QMD_TRACE_HEAD(head); \
00535 QMD_TRACE_ELEM(&(elm)->field); \
00536 } while (0)
00537
00538 #define TAILQ_LAST(head, headname) \
00539 (*(((struct headname *)((head)->tqh_last))->tqh_last))
00540
00541 #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
00542
00543 #define TAILQ_PREV(elm, headname, field) \
00544 (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
00545
00546 #define TAILQ_REMOVE(head, elm, field) do { \
00547 if ((TAILQ_NEXT((elm), field)) != NULL) \
00548 TAILQ_NEXT((elm), field)->field.tqe_prev = \
00549 (elm)->field.tqe_prev; \
00550 else { \
00551 (head)->tqh_last = (elm)->field.tqe_prev; \
00552 QMD_TRACE_HEAD(head); \
00553 } \
00554 *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
00555 TRASHIT((elm)->field.tqe_next); \
00556 TRASHIT((elm)->field.tqe_prev); \
00557 QMD_TRACE_ELEM(&(elm)->field); \
00558 } while (0)
00559
00560 #if defined(__cplusplus)
00561 }
00562 #endif
00563 #endif