From 3401d55726febf019486edb4274dcc59c75cd57d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 14 Oct 2024 18:57:08 +0200 Subject: [PATCH] zend_weakrefs: Add `zend_weakrefs_hash_(clean|destroy)()` (#16439) These are equivalent to `zend_hash_clean()` and `zend_hash_destroy()` respectively, but take care of correctly unregistering the weak references to the keys. This addition rounds off the weakmap functionality added in 471102edcd19c79be2541188ae8a211a2cbc85bb by taking one possible footgun away from the user. --- Zend/zend_weakrefs.c | 7 +++++++ Zend/zend_weakrefs.h | 6 ++++++ ext/zend_test/test.c | 6 +----- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Zend/zend_weakrefs.c b/Zend/zend_weakrefs.c index aea46e49341..6be659d3dda 100644 --- a/Zend/zend_weakrefs.c +++ b/Zend/zend_weakrefs.c @@ -183,6 +183,13 @@ ZEND_API zend_result zend_weakrefs_hash_del(HashTable *ht, zend_object *key) { return FAILURE; } +ZEND_API void zend_weakrefs_hash_clean(HashTable *ht) { + zend_ulong obj_key; + ZEND_HASH_FOREACH_NUM_KEY(ht, obj_key) { + zend_weakrefs_hash_del(ht, zend_weakref_key_to_object(obj_key)); + } ZEND_HASH_FOREACH_END(); +} + void zend_weakrefs_init(void) { zend_hash_init(&EG(weakrefs), 8, NULL, NULL, 0); } diff --git a/Zend/zend_weakrefs.h b/Zend/zend_weakrefs.h index 5b1c8ea1c32..00d4fbcc6bc 100644 --- a/Zend/zend_weakrefs.h +++ b/Zend/zend_weakrefs.h @@ -41,6 +41,12 @@ static zend_always_inline void *zend_weakrefs_hash_add_ptr(HashTable *ht, zend_o return NULL; } } +ZEND_API void zend_weakrefs_hash_clean(HashTable *ht); +static zend_always_inline void zend_weakrefs_hash_destroy(HashTable *ht) { + zend_weakrefs_hash_clean(ht); + ZEND_ASSERT(zend_hash_num_elements(ht) == 0); + zend_hash_destroy(ht); +} /* Because php uses the raw numbers as a hash function, raw pointers will lead to hash collisions. * We have a guarantee that the lowest ZEND_MM_ALIGNED_OFFSET_LOG2 bits of a pointer are zero. diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index 06df0655a6f..37b3f7a2c5e 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -1354,11 +1354,7 @@ PHP_RINIT_FUNCTION(zend_test) PHP_RSHUTDOWN_FUNCTION(zend_test) { - zend_ulong obj_key; - ZEND_HASH_FOREACH_NUM_KEY(&ZT_G(global_weakmap), obj_key) { - zend_weakrefs_hash_del(&ZT_G(global_weakmap), zend_weakref_key_to_object(obj_key)); - } ZEND_HASH_FOREACH_END(); - zend_hash_destroy(&ZT_G(global_weakmap)); + zend_weakrefs_hash_destroy(&ZT_G(global_weakmap)); if (ZT_G(zend_test_heap)) { free(ZT_G(zend_test_heap));