diff options
author | Nick Mathewson <nickm@torproject.org> | 2012-02-20 13:56:13 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2012-02-20 13:56:13 -0500 |
commit | 8dbcf8d62ba0e1c5b408e22babe55e9490ea2404 (patch) | |
tree | 4e5f94801a3b0064ef2b0bc4893ed2410d22e644 /util-internal.h | |
parent | 65bc91c210b75ae924111919eee56ec54ecd27ee (diff) | |
parent | cad5753587c1b4bed7b76f6572a9205f4f2d3ac9 (diff) | |
download | libevent-8dbcf8d62ba0e1c5b408e22babe55e9490ea2404.tar.gz |
Merge branch '21_eventlist_v3_squashed'
Diffstat (limited to 'util-internal.h')
-rw-r--r-- | util-internal.h | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/util-internal.h b/util-internal.h index 162dd040..48ba41d3 100644 --- a/util-internal.h +++ b/util-internal.h @@ -133,6 +133,79 @@ extern "C" { #define EVUTIL_SHUT_BOTH 2 #endif +/* Helper: Verify that all the elements in 'dlist' are internally consistent. + * Checks for circular lists and bad prev/next pointers. + * + * Example usage: + * EVUTIL_ASSERT_LIST_OK(eventlist, event, ev_next); + */ +#define EVUTIL_ASSERT_LIST_OK(dlist, type, field) do { \ + struct type *elm1, *elm2, **nextp; \ + if (LIST_EMPTY((dlist))) \ + break; \ + \ + /* Check list for circularity using Floyd's */ \ + /* 'Tortoise and Hare' algorithm */ \ + elm1 = LIST_FIRST((dlist)); \ + elm2 = LIST_NEXT(elm1, field); \ + while (elm1 && elm2) { \ + EVUTIL_ASSERT(elm1 != elm2); \ + elm1 = LIST_NEXT(elm1, field); \ + elm2 = LIST_NEXT(elm2, field); \ + if (!elm2) \ + break; \ + EVUTIL_ASSERT(elm1 != elm2); \ + elm2 = LIST_NEXT(elm2, field); \ + } \ + \ + /* Now check next and prev pointers for consistency. */ \ + nextp = &LIST_FIRST((dlist)); \ + elm1 = LIST_FIRST((dlist)); \ + while (elm1) { \ + EVUTIL_ASSERT(*nextp == elm1); \ + EVUTIL_ASSERT(nextp == elm1->field.le_prev); \ + nextp = &LIST_NEXT(elm1, field); \ + elm1 = *nextp; \ + } \ + } while (0) + +/* Helper: Verify that all the elements in a TAILQ are internally consistent. + * Checks for circular lists and bad prev/next pointers. + * + * Example usage: + * EVUTIL_ASSERT_TAILQ_OK(activelist, event, ev_active_next); + */ +#define EVUTIL_ASSERT_TAILQ_OK(tailq, type, field) do { \ + struct type *elm1, *elm2, **nextp; \ + if (TAILQ_EMPTY((tailq))) \ + break; \ + \ + /* Check list for circularity using Floyd's */ \ + /* 'Tortoise and Hare' algorithm */ \ + elm1 = TAILQ_FIRST((tailq)); \ + elm2 = TAILQ_NEXT(elm1, field); \ + while (elm1 && elm2) { \ + EVUTIL_ASSERT(elm1 != elm2); \ + elm1 = TAILQ_NEXT(elm1, field); \ + elm2 = TAILQ_NEXT(elm2, field); \ + if (!elm2) \ + break; \ + EVUTIL_ASSERT(elm1 != elm2); \ + elm2 = TAILQ_NEXT(elm2, field); \ + } \ + \ + /* Now check next and prev pointers for consistency. */ \ + nextp = &TAILQ_FIRST((tailq)); \ + elm1 = TAILQ_FIRST((tailq)); \ + while (elm1) { \ + EVUTIL_ASSERT(*nextp == elm1); \ + EVUTIL_ASSERT(nextp == elm1->field.tqe_prev); \ + nextp = &TAILQ_NEXT(elm1, field); \ + elm1 = *nextp; \ + } \ + EVUTIL_ASSERT(nextp == (tailq)->tqh_last); \ + } while (0) + /* Locale-independent replacements for some ctypes functions. Use these * when you care about ASCII's notion of character types, because you are about * to send those types onto the wire. |