diff --git a/epan/wmem/wmem_core.c b/epan/wmem/wmem_core.c index 0d0c91fdf2..08d51ff1f4 100644 --- a/epan/wmem/wmem_core.c +++ b/epan/wmem/wmem_core.c @@ -113,7 +113,8 @@ 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, final); + wmem_call_cleanup_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 a9b59316c2..7853e21370 100644 --- a/epan/wmem/wmem_test.c +++ b/epan/wmem/wmem_test.c @@ -74,19 +74,21 @@ wmem_allocator_force_new(const wmem_allocator_type_t type) /* Some helpers for properly testing callback functionality */ wmem_allocator_t *expected_allocator; void *expected_user_data; -gboolean expected_final; +wmem_cb_event_t expected_event; int cb_called_count; int cb_continue_count; gboolean value_seen[CONTAINER_ITERS]; -static void -wmem_test_cb(wmem_allocator_t *allocator, gboolean final, void *user_data) +static gboolean +wmem_test_cb(wmem_allocator_t *allocator, wmem_cb_event_t event, + void *user_data) { g_assert(allocator == expected_allocator); - g_assert(final == expected_final); - g_assert(user_data == expected_user_data); + g_assert(event == expected_event); cb_called_count++; + + return *(gboolean*)user_data; } static gboolean @@ -109,24 +111,25 @@ static void wmem_test_allocator_callbacks(void) { wmem_allocator_t *allocator; + gboolean t = TRUE; + gboolean f = FALSE; allocator = wmem_allocator_force_new(WMEM_ALLOCATOR_STRICT); expected_allocator = allocator; - expected_user_data = GINT_TO_POINTER(42); -#define REG_TEST_CB(RECUR) do { \ - wmem_register_cleanup_callback(expected_allocator, (RECUR), \ - &wmem_test_cb, GINT_TO_POINTER(42)); \ +#define REG_TEST_CB(UDATA) do { \ + wmem_register_cleanup_callback(expected_allocator, \ + &wmem_test_cb, (UDATA)); \ } while (0); - REG_TEST_CB(FALSE); - REG_TEST_CB(TRUE); - REG_TEST_CB(FALSE); - REG_TEST_CB(FALSE); - REG_TEST_CB(TRUE); + REG_TEST_CB(&f); + REG_TEST_CB(&f); + REG_TEST_CB(&t); + REG_TEST_CB(&t); + REG_TEST_CB(&f); - expected_final = FALSE; + expected_event = WMEM_CB_FREE_EVENT; cb_called_count = 0; wmem_free_all(allocator); @@ -140,8 +143,8 @@ wmem_test_allocator_callbacks(void) wmem_free_all(allocator); g_assert(cb_called_count == 2); - REG_TEST_CB(TRUE); - REG_TEST_CB(FALSE); + REG_TEST_CB(&f); + REG_TEST_CB(&t); cb_called_count = 0; wmem_free_all(allocator); @@ -151,9 +154,9 @@ wmem_test_allocator_callbacks(void) wmem_free_all(allocator); g_assert(cb_called_count == 3); - REG_TEST_CB(FALSE); + REG_TEST_CB(&t); - expected_final = TRUE; + expected_event = WMEM_CB_DESTROY_EVENT; cb_called_count = 0; wmem_destroy_allocator(allocator); g_assert(cb_called_count == 4); diff --git a/epan/wmem/wmem_tree.c b/epan/wmem/wmem_tree.c index 95f4107551..a523ec77f6 100644 --- a/epan/wmem/wmem_tree.c +++ b/epan/wmem/wmem_tree.c @@ -230,13 +230,15 @@ wmem_tree_new(wmem_allocator_t *allocator) return tree; } -static void -wmem_tree_reset(wmem_allocator_t *allocator _U_, gboolean final _U_, +static gboolean +wmem_tree_reset(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_, void *user_data) { wmem_tree_t *tree = (wmem_tree_t *)user_data; tree->root = NULL; + + return TRUE; } wmem_tree_t * @@ -249,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, TRUE, wmem_tree_reset, tree); + wmem_register_cleanup_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 3eda0790a3..8705cdaa64 100644 --- a/epan/wmem/wmem_user_cb.c +++ b/epan/wmem/wmem_user_cb.c @@ -33,13 +33,13 @@ typedef struct _wmem_user_cb_container_t { wmem_user_cb_t cb; void *user_data; struct _wmem_user_cb_container_t *next; - gboolean recurring; } wmem_user_cb_container_t; void -wmem_call_cleanup_callbacks(wmem_allocator_t *allocator, gboolean final) +wmem_call_cleanup_callbacks(wmem_allocator_t *allocator, wmem_cb_event_t event) { wmem_user_cb_container_t **prev, *cur; + gboolean again; prev = &(allocator->callbacks); cur = allocator->callbacks; @@ -47,11 +47,11 @@ wmem_call_cleanup_callbacks(wmem_allocator_t *allocator, gboolean final) while (cur) { /* call it */ - cur->cb(allocator, final, cur->user_data); + again = cur->cb(allocator, event, cur->user_data); - /* if it was a one-time callback, or this is being triggered by - * the final destruction of the allocator, remove the callback */ - if (! cur->recurring || final) { + /* if the callback requested deregistration, or this is being triggered + * by the final destruction of the allocator, remove the callback */ + if (! again || event == WMEM_CB_DESTROY_EVENT) { *prev = cur->next; g_slice_free(wmem_user_cb_container_t, cur); cur = *prev; @@ -64,7 +64,7 @@ wmem_call_cleanup_callbacks(wmem_allocator_t *allocator, gboolean final) } void -wmem_register_cleanup_callback(wmem_allocator_t *allocator, gboolean recurring, +wmem_register_cleanup_callback(wmem_allocator_t *allocator, wmem_user_cb_t callback, void *user_data) { wmem_user_cb_container_t *container; @@ -73,7 +73,6 @@ wmem_register_cleanup_callback(wmem_allocator_t *allocator, gboolean recurring, container->cb = callback; container->user_data = user_data; - container->recurring = recurring; container->next = allocator->callbacks; allocator->callbacks = container; diff --git a/epan/wmem/wmem_user_cb.h b/epan/wmem/wmem_user_cb.h index 929c8dc030..0491d76b07 100644 --- a/epan/wmem/wmem_user_cb.h +++ b/epan/wmem/wmem_user_cb.h @@ -41,15 +41,21 @@ extern "C" { * @{ */ +/** The events that can trigger a callback. */ +typedef enum _wmem_cb_event_t { + WMEM_CB_FREE_EVENT, /**< wmem_free_all() */ + WMEM_CB_DESTROY_EVENT /**< wmem_destroy_allocator() */ +} wmem_cb_event_t; + /** Function signature for registered user callbacks. * * @param allocator The allocator that triggered this callback. - * @param final Whether this is was triggered due to the allocator being - * destroyed (TRUE) or simply a call to wmem_free_all() (FALSE). + * @param event The event type that triggered this callback. * @param user_data Whatever user_data was originally passed to the call to - * wmem_register_cleanup_callback(). + * wmem_register_cleanup_callback(). + * @return FALSE to unregister the callback, TRUE otherwise. */ -typedef void (*wmem_user_cb_t) (wmem_allocator_t *, gboolean, void *); +typedef gboolean (*wmem_user_cb_t) (wmem_allocator_t*, wmem_cb_event_t, void*); /** Register a callback function with the given allocator pool. * @@ -67,7 +73,7 @@ typedef void (*wmem_user_cb_t) (wmem_allocator_t *, gboolean, void *); */ WS_DLL_PUBLIC void -wmem_register_cleanup_callback(wmem_allocator_t *allocator, gboolean recurring, +wmem_register_cleanup_callback(wmem_allocator_t *allocator, wmem_user_cb_t callback, void *user_data); /** @} diff --git a/epan/wmem/wmem_user_cb_int.h b/epan/wmem/wmem_user_cb_int.h index a8bae60666..d4ff7abde1 100644 --- a/epan/wmem/wmem_user_cb_int.h +++ b/epan/wmem/wmem_user_cb_int.h @@ -31,9 +31,11 @@ extern "C" { #endif /* __cplusplus */ #include +#include +WS_DLL_LOCAL void -wmem_call_cleanup_callbacks(wmem_allocator_t *allocator, gboolean final); +wmem_call_cleanup_callbacks(wmem_allocator_t *allocator, wmem_cb_event_t event); #ifdef __cplusplus }