diff options
-rw-r--r-- | epan/wmem/wmem_core.c | 2 | ||||
-rw-r--r-- | epan/wmem/wmem_test.c | 34 | ||||
-rw-r--r-- | epan/wmem/wmem_tree.c | 2 | ||||
-rw-r--r-- | epan/wmem/wmem_user_cb.c | 32 | ||||
-rw-r--r-- | epan/wmem/wmem_user_cb.h | 15 | ||||
-rw-r--r-- | epan/wmem/wmem_user_cb_int.h | 2 |
6 files changed, 63 insertions, 24 deletions
diff --git a/epan/wmem/wmem_core.c b/epan/wmem/wmem_core.c index 08d51ff1f4..f502b4defd 100644 --- a/epan/wmem/wmem_core.c +++ b/epan/wmem/wmem_core.c @@ -113,7 +113,7 @@ wmem_memdup(wmem_allocator_t *allocator, const void *source, const size_t size) static void wmem_free_all_real(wmem_allocator_t *allocator, gboolean final) { - wmem_call_cleanup_callbacks(allocator, + wmem_call_callbacks(allocator, final ? WMEM_CB_DESTROY_EVENT : WMEM_CB_FREE_EVENT); allocator->free_all(allocator->private_data); } diff --git a/epan/wmem/wmem_test.c b/epan/wmem/wmem_test.c index 7853e21370..83139a4e64 100644 --- a/epan/wmem/wmem_test.c +++ b/epan/wmem/wmem_test.c @@ -113,21 +113,17 @@ wmem_test_allocator_callbacks(void) wmem_allocator_t *allocator; gboolean t = TRUE; gboolean f = FALSE; + guint cb_id; allocator = wmem_allocator_force_new(WMEM_ALLOCATOR_STRICT); expected_allocator = allocator; -#define REG_TEST_CB(UDATA) do { \ - wmem_register_cleanup_callback(expected_allocator, \ - &wmem_test_cb, (UDATA)); \ - } while (0); - - REG_TEST_CB(&f); - REG_TEST_CB(&f); - REG_TEST_CB(&t); - REG_TEST_CB(&t); - REG_TEST_CB(&f); + wmem_register_callback(expected_allocator, &wmem_test_cb, &f); + wmem_register_callback(expected_allocator, &wmem_test_cb, &f); + cb_id = wmem_register_callback(expected_allocator, &wmem_test_cb, &t); + wmem_register_callback(expected_allocator, &wmem_test_cb, &t); + wmem_register_callback(expected_allocator, &wmem_test_cb, &f); expected_event = WMEM_CB_FREE_EVENT; @@ -143,23 +139,29 @@ wmem_test_allocator_callbacks(void) wmem_free_all(allocator); g_assert(cb_called_count == 2); - REG_TEST_CB(&f); - REG_TEST_CB(&t); - + wmem_unregister_callback(allocator, cb_id); cb_called_count = 0; wmem_free_all(allocator); - g_assert(cb_called_count == 4); + g_assert(cb_called_count == 1); + + cb_id = wmem_register_callback(expected_allocator, &wmem_test_cb, &f); + wmem_register_callback(expected_allocator, &wmem_test_cb, &t); cb_called_count = 0; wmem_free_all(allocator); g_assert(cb_called_count == 3); - REG_TEST_CB(&t); + wmem_unregister_callback(allocator, cb_id); + cb_called_count = 0; + wmem_free_all(allocator); + g_assert(cb_called_count == 2); + + wmem_register_callback(expected_allocator, &wmem_test_cb, &t); expected_event = WMEM_CB_DESTROY_EVENT; cb_called_count = 0; wmem_destroy_allocator(allocator); - g_assert(cb_called_count == 4); + g_assert(cb_called_count == 3); } static void diff --git a/epan/wmem/wmem_tree.c b/epan/wmem/wmem_tree.c index a523ec77f6..929d5f0c53 100644 --- a/epan/wmem/wmem_tree.c +++ b/epan/wmem/wmem_tree.c @@ -251,7 +251,7 @@ wmem_tree_new_autoreset(wmem_allocator_t *master, wmem_allocator_t *slave) tree->allocator = slave; tree->root = NULL; - wmem_register_cleanup_callback(slave, wmem_tree_reset, tree); + wmem_register_callback(slave, wmem_tree_reset, tree); return tree; } diff --git a/epan/wmem/wmem_user_cb.c b/epan/wmem/wmem_user_cb.c index 8705cdaa64..f2334239ce 100644 --- a/epan/wmem/wmem_user_cb.c +++ b/epan/wmem/wmem_user_cb.c @@ -33,10 +33,11 @@ typedef struct _wmem_user_cb_container_t { wmem_user_cb_t cb; void *user_data; struct _wmem_user_cb_container_t *next; + guint id; } wmem_user_cb_container_t; void -wmem_call_cleanup_callbacks(wmem_allocator_t *allocator, wmem_cb_event_t event) +wmem_call_callbacks(wmem_allocator_t *allocator, wmem_cb_event_t event) { wmem_user_cb_container_t **prev, *cur; gboolean again; @@ -63,19 +64,44 @@ wmem_call_cleanup_callbacks(wmem_allocator_t *allocator, wmem_cb_event_t event) } } -void -wmem_register_cleanup_callback(wmem_allocator_t *allocator, +guint +wmem_register_callback(wmem_allocator_t *allocator, wmem_user_cb_t callback, void *user_data) { wmem_user_cb_container_t *container; + static guint next_id = 0; container = g_slice_new(wmem_user_cb_container_t); container->cb = callback; container->user_data = user_data; container->next = allocator->callbacks; + container->id = next_id++; allocator->callbacks = container; + + return container->id; +} + +void +wmem_unregister_callback(wmem_allocator_t *allocator, guint id) +{ + wmem_user_cb_container_t **prev, *cur; + + prev = &(allocator->callbacks); + cur = allocator->callbacks; + + while (cur) { + + if (cur->id == id) { + *prev = cur->next; + g_slice_free(wmem_user_cb_container_t, cur); + return; + } + + prev = &(cur->next); + cur = cur->next; + } } /* diff --git a/epan/wmem/wmem_user_cb.h b/epan/wmem/wmem_user_cb.h index 0491d76b07..3477167fb1 100644 --- a/epan/wmem/wmem_user_cb.h +++ b/epan/wmem/wmem_user_cb.h @@ -70,11 +70,22 @@ typedef gboolean (*wmem_user_cb_t) (wmem_allocator_t*, wmem_cb_event_t, void*); * that this pointer is not freed when a callback is finished, * you have to do that yourself in the callback, or just * allocate it in the appropriate wmem pool. + * @return ID of this callback that can be passed back to + * wmem_unregister_callback(). + */ +WS_DLL_PUBLIC +guint +wmem_register_callback(wmem_allocator_t *allocator, wmem_user_cb_t callback, + void *user_data); + +/** Unregister the callback function with the given ID. + * + * @param allocator The allocator from which to unregister the callback. + * @param id The callback id as returned from wmem_register_callback(). */ WS_DLL_PUBLIC void -wmem_register_cleanup_callback(wmem_allocator_t *allocator, - wmem_user_cb_t callback, void *user_data); +wmem_unregister_callback(wmem_allocator_t *allocator, guint id); /** @} * @} */ diff --git a/epan/wmem/wmem_user_cb_int.h b/epan/wmem/wmem_user_cb_int.h index 55bb4e28aa..26cfbc862c 100644 --- a/epan/wmem/wmem_user_cb_int.h +++ b/epan/wmem/wmem_user_cb_int.h @@ -35,7 +35,7 @@ extern "C" { WS_DLL_LOCAL void -wmem_call_cleanup_callbacks(wmem_allocator_t *allocator, wmem_cb_event_t event); +wmem_call_callbacks(wmem_allocator_t *allocator, wmem_cb_event_t event); #ifdef __cplusplus } |