From bd7b76bacf0f1c8027e2676b007fbc281dd82f80 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 22 Jan 2021 16:46:04 +0300 Subject: [PATCH] [Core] Add new switch_core_hash_insert_pointer(switch_hash_t *hash, const void *data) API to be able to insert data into a hash with an auto-generated key based on the data pointer. Cleanup switch_loadable_module_process() to not generate hash keys for stored events itself. Add unit-test. --- src/include/switch_core.h | 8 ++++ src/switch_core_hash.c | 17 ++++++++ src/switch_loadable_module.c | 83 ++++++++---------------------------- tests/unit/switch_core.c | 31 ++++++++++++++ 4 files changed, 74 insertions(+), 65 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 7592362c5c..b6b3efbd90 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1428,6 +1428,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_init_case(_Out_ switch_hash_t * */ SWITCH_DECLARE(switch_status_t) switch_core_hash_destroy(_Inout_ switch_hash_t **hash); +/*! + \brief Insert data into a hash with an auto-generated key based on the data pointer + \param hash the hash to add data to + \param data unique pointer to add + \return SWITCH_STATUS_SUCCESS if the data is added +*/ +SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_pointer(switch_hash_t *hash, const void *data); + /*! \brief Insert data into a hash and set flags so the value is automatically freed on delete \param hash the hash to add data to diff --git a/src/switch_core_hash.c b/src/switch_core_hash.c index 06d0475852..1f13a44a6f 100644 --- a/src/switch_core_hash.c +++ b/src/switch_core_hash.c @@ -55,6 +55,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_destroy(switch_hash_t **hash) return SWITCH_STATUS_SUCCESS; } +SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_pointer(switch_hash_t *hash, const void *data) +{ + size_t bytes_required = snprintf(NULL, 0, "%p", data) + 1; + char *dkey = malloc(bytes_required); + size_t bytes_written = snprintf(dkey, bytes_required, "%p", data); + + if (bytes_written > 0 && bytes_written < bytes_required) { + if (switch_hashtable_insert_destructor(hash, dkey, (void *)data, HASHTABLE_FLAG_FREE_KEY | HASHTABLE_DUP_CHECK, NULL)) { + return SWITCH_STATUS_SUCCESS; + } + } + + switch_safe_free(dkey); + + return SWITCH_STATUS_FALSE; +} + SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_auto_free(switch_hash_t *hash, const char *key, const void *data) { char *dkey = strdup(key); diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 268b76f1c4..5442cca03a 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -156,25 +156,8 @@ static void switch_loadable_module_runtime(void) static switch_status_t switch_loadable_module_process(char *key, switch_loadable_module_t *new_module, switch_hash_t *event_hash) { switch_event_t *event; - int *event_num = NULL; - char str_event_num[12]; - void *val; int added = 0; - if (event_hash) { - if ((val = switch_core_hash_find(event_hash, "0"))) { - event_num = (int*)val; - } else { - if (!(event_num = malloc(sizeof(int)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Allocation error.\n"); - return SWITCH_STATUS_MEMERR; - } - - *event_num = 0; - switch_core_hash_insert(event_hash, "0", (const void*)event_num); - } - } - new_module->key = switch_core_strdup(new_module->pool, key); switch_mutex_lock(loadable_modules.mutex); @@ -197,8 +180,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable if (!event_hash) { switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -271,8 +253,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -300,8 +281,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -329,8 +309,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -360,8 +339,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -391,8 +369,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -422,8 +399,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -453,8 +429,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -489,8 +464,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -535,8 +509,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -572,8 +545,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -601,8 +573,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -630,8 +601,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -659,8 +629,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -688,8 +657,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -723,8 +691,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -758,8 +725,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -781,8 +747,7 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable switch_event_fire(&event); } else { - sprintf(str_event_num, "%i", ++*event_num); - switch_core_hash_insert(event_hash, (const char*)str_event_num, (const void*)event); + switch_core_hash_insert_pointer(event_hash, (const void*)event); } added++; @@ -2211,10 +2176,6 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(switch_bool_t autolo if (switch_loadable_module_load_module_ex((char *)path, (char *)val, SWITCH_FALSE, global, &err, SWITCH_LOADABLE_MODULE_TYPE_PRELOAD, event_hash) == SWITCH_STATUS_GENERR) { if (critical && switch_true(critical)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load critical module '%s', abort()\n", val); - - if ((hash_val = switch_core_hash_find(event_hash, "0"))) { - switch_safe_free(hash_val); - } switch_core_hash_destroy(&event_hash); abort(); @@ -2233,19 +2194,11 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(switch_bool_t autolo if (switch_core_sqldb_init(&err) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Loading modules interrupted. [Error: %s]\n", err); - if ((hash_val = switch_core_hash_find(event_hash, "0"))) { - switch_safe_free(hash_val); - } switch_core_hash_destroy(&event_hash); return SWITCH_STATUS_GENERR; } /* sqldb is ready. Fire holding events! */ - if ((hash_val = switch_core_hash_find(event_hash, "0"))) { - switch_safe_free(hash_val); - switch_core_hash_delete(event_hash, "0"); - } - for (hi = switch_core_hash_first(event_hash); hi; hi = switch_core_hash_next(&hi)) { switch_core_hash_this(hi, NULL, NULL, &hash_val); event = (switch_event_t *)hash_val; diff --git a/tests/unit/switch_core.c b/tests/unit/switch_core.c index af52ab9495..c8c268387b 100644 --- a/tests/unit/switch_core.c +++ b/tests/unit/switch_core.c @@ -314,6 +314,37 @@ FST_CORE_BEGIN("./conf") free(item); } FST_TEST_END() + + FST_TEST_BEGIN(test_switch_core_hash_insert_pointer) + { + int i, sum = 0; + switch_hash_index_t *hi; + switch_hash_t *hash = NULL; + switch_core_hash_init(&hash); + fst_requires(hash); + + for (i = 0; i < 10; i++) { + int *num = malloc(sizeof(int)); + *num = i; + fst_check_int_equals(switch_core_hash_insert_pointer(hash, (void*)num), SWITCH_STATUS_SUCCESS); + } + + i = 0; + for (hi = switch_core_hash_first(hash); hi; hi = switch_core_hash_next(&hi)) { + void *hash_val; + switch_core_hash_this(hi, NULL, NULL, &hash_val); + sum += *(int*)hash_val; + free(hash_val); + i++; + } + + fst_check_int_equals(i, 10); + fst_check_int_equals(sum, 45); + + switch_core_hash_destroy(&hash); + fst_requires(hash == NULL); + } + FST_TEST_END() } FST_SUITE_END() }