summaryrefslogtreecommitdiff
path: root/util-internal.h
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2012-02-20 13:56:13 -0500
committerNick Mathewson <nickm@torproject.org>2012-02-20 13:56:13 -0500
commit8dbcf8d62ba0e1c5b408e22babe55e9490ea2404 (patch)
tree4e5f94801a3b0064ef2b0bc4893ed2410d22e644 /util-internal.h
parent65bc91c210b75ae924111919eee56ec54ecd27ee (diff)
parentcad5753587c1b4bed7b76f6572a9205f4f2d3ac9 (diff)
downloadlibevent-8dbcf8d62ba0e1c5b408e22babe55e9490ea2404.tar.gz
Merge branch '21_eventlist_v3_squashed'
Diffstat (limited to 'util-internal.h')
-rw-r--r--util-internal.h73
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.