From fbcb86226581cdcc66fc7b633b505906c207a4cd Mon Sep 17 00:00:00 2001 From: Tamas Cseke Date: Thu, 24 May 2012 09:35:23 +0200 Subject: [PATCH] add thread safe hash multi delete function and make callback optional --- src/include/switch_core.h | 22 +++++++++++++++++++++- src/switch_core_hash.c | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 9803c6708b..6e67989b90 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1277,7 +1277,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_locked(_In_ switch_hash_ \brief Delete data from a hash based on desired key \param hash the hash to delete from \param key the key from which to delete the data - \param mutex optional rwlock to wrlock + \param rwlock optional rwlock to wrlock \return SWITCH_STATUS_SUCCESS if the data is deleted */ SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_wrlock(_In_ switch_hash_t *hash, _In_z_ const char *key, _In_opt_ switch_thread_rwlock_t *rwlock); @@ -1290,6 +1290,26 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_wrlock(_In_ switch_hash_ */ SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_multi(_In_ switch_hash_t *hash, _In_ switch_hash_delete_callback_t callback, _In_opt_ void *pData); +/*! + \brief Delete data from a hash based on callback function + \param hash the hash to delete from + \param callback the function to call which returns SWITCH_TRUE to delete, SWITCH_FALSE to preserve + \param rwlock optional rwlock to wrlock + \return SWITCH_STATUS_SUCCESS if any data is deleted +*/ + +SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_multi_wrlock(_In_ switch_hash_t *hash, _In_ switch_hash_delete_callback_t callback, _In_opt_ void *pData, _In_ switch_thread_rwlock_t *rwlock); + +/*! + \brief Delete data from a hash based on callback function + \param hash the hash to delete from + \param callback the function to call which returns SWITCH_TRUE to delete, SWITCH_FALSE to preserve + \param mutex optional mutex to lock + \return SWITCH_STATUS_SUCCESS if any data is deleted +*/ + +SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_multi_locked(_In_ switch_hash_t *hash, _In_ switch_hash_delete_callback_t callback, _In_opt_ void *pData, _In_ switch_mutex_t *mutex); + /*! \brief Retrieve data from a given hash \param hash the hash to retrieve from diff --git a/src/switch_core_hash.c b/src/switch_core_hash.c index 4ac3d2620e..ed5c4c2ca4 100644 --- a/src/switch_core_hash.c +++ b/src/switch_core_hash.c @@ -157,7 +157,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_multi(switch_hash_t *has switch_event_create_subclass(&event, SWITCH_EVENT_CLONE, NULL); switch_assert(event); - /* iterate through the hash, call callback, if callback returns true, put the key on the list (event) + /* iterate through the hash, call callback, if callback is NULL or returns true, put the key on the list (event) When done, iterate through the list deleting hash entries */ @@ -165,7 +165,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_multi(switch_hash_t *has const void *key; void *val; switch_hash_this(hi, &key, NULL, &val); - if (callback(key, val, pData)) { + if (!callback || callback(key, val, pData)) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delete", (const char *) key); } } @@ -182,6 +182,40 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_multi(switch_hash_t *has return status; } +SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_multi_wrlock(switch_hash_t *hash, switch_hash_delete_callback_t callback, void *pData, switch_thread_rwlock_t *rwlock) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (rwlock) { + switch_thread_rwlock_wrlock(rwlock); + } + + status = switch_core_hash_delete_multi(hash, callback, pData); + + if (rwlock) { + switch_thread_rwlock_unlock(rwlock); + } + + return status; +} + +SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_multi_locked(switch_hash_t *hash, switch_hash_delete_callback_t callback, void *pData, switch_mutex_t *mutex) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (mutex) { + switch_mutex_lock(mutex); + } + + status = switch_core_hash_delete_multi(hash, callback, pData); + + if (mutex) { + switch_mutex_unlock(mutex); + } + + return status; +} + SWITCH_DECLARE(void *) switch_core_hash_find(switch_hash_t *hash, const char *key) {