aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/wmem/wmem_core.c2
-rw-r--r--epan/wmem/wmem_test.c34
-rw-r--r--epan/wmem/wmem_tree.c2
-rw-r--r--epan/wmem/wmem_user_cb.c32
-rw-r--r--epan/wmem/wmem_user_cb.h15
-rw-r--r--epan/wmem/wmem_user_cb_int.h2
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
}