diff options
author | Brian Nguyen <brnguyen@nvidia.com> | 2014-10-02 15:58:47 -0700 |
---|---|---|
committer | brnguyen <brnguyen@nvidia.com> | 2014-10-28 15:37:28 -0700 |
commit | b7b6e43b3a72174582a192d3ace77df946182816 (patch) | |
tree | a524e32bc1354418e2b46a17f56700e26bf2e8d6 /include | |
parent | 81523012da5a4ecc2a656a6ccaef0b596c401e0f (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.h | 43 |
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 |