summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorBrian Nguyen <brnguyen@nvidia.com>2014-10-02 15:58:47 -0700
committerbrnguyen <brnguyen@nvidia.com>2014-10-28 15:37:28 -0700
commitb7b6e43b3a72174582a192d3ace77df946182816 (patch)
treea524e32bc1354418e2b46a17f56700e26bf2e8d6 /include
parent81523012da5a4ecc2a656a6ccaef0b596c401e0f (diff)
Add LKDHASH_TEARDOWN() macro to handle hash table cleanup
This macro frees all entries in a locked hash table, and either re-initializes the table's lock for fork recovery, or destroys the lock, in which case the hash table is fully torn down and must be re-initialized before it can be used. Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Diffstat (limited to 'include')
-rw-r--r--include/lkdhash.h43
1 files changed, 43 insertions, 0 deletions
diff --git a/include/lkdhash.h b/include/lkdhash.h
index e8349c5..3557515 100644
--- a/include/lkdhash.h
+++ b/include/lkdhash.h
@@ -40,4 +40,47 @@
*/
#define _LH(_lockedhash) ((_lockedhash).hash)
+#define LKDHASH_TEARDOWN_2(imp, _lockedhash, _param, _cur, _tmp, _cleanup) do { \
+ LKDHASH_WRLOCK(imp, _lockedhash); \
+ HASH_ITER(hh, _LH( _lockedhash), _cur, _tmp) { \
+ HASH_DEL(_LH(_lockedhash), _cur); \
+ if (_cleanup) { \
+ _cleanup(_param, _cur); \
+ } \
+ free(_cur); \
+ } \
+ assert(!_LH(_lockedhash)); \
+ LKDHASH_UNLOCK(imp, _lockedhash); \
+} while (0)
+
+/*!
+ * Macro for deleting all entries in a locked hash, as well as the protecting
+ * lock. Assumes that hash entries have been allocated using malloc(3) or
+ * similar and are safe to pass into free(3).
+ *
+ * _ht indicates the type of the hash table to use, and _lh indicates the
+ * hash table variable.
+ *
+ * _cleanup is a callback function which takes (_void *, _ht *) as arguments,
+ * or NULL.
+ *
+ * _param is an extra parmeter to pass into the callback function of type
+ * (void *).
+ *
+ * _reset indicates whether the lock needs to be re-initialized (for fork
+ * handling).
+ */
+#define LKDHASH_TEARDOWN(imp, _ht, _lh, _cleanup, _param, _reset) do { \
+ _ht *cur ## _ht, *tmp ## _ht; \
+ typedef void (*pfnCleanup ## _ht)(void *p, _ht *h); \
+ pfnCleanup ## _ht pCleanup ## _ht = _cleanup; \
+ LKDHASH_TEARDOWN_2(imp, _lh, _param, cur ## _ht, \
+ tmp ## _ht, pCleanup ## _ht); \
+ if (_reset) { \
+ (imp).rwlock_init(&(_lh).lock, NULL); \
+ } else { \
+ (imp).rwlock_destroy(&(_lh).lock); \
+ } \
+} while (0)
+
#endif