From eabb445a9f39917efb71c7cb47543df288e2ef21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 14 Oct 2024 17:27:48 +0200 Subject: [PATCH] zend_weakrefs: Add `zend_weakrefs_hash_(clean|destroy)()` 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 aea46e493410e..6be659d3dda5d 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 5b1c8ea1c325d..00d4fbcc6bc4c 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 06df0655a6fe8..37b3f7a2c5e49 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));