php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #74053
Patch class_entry_gone_before_dtor revision 2017-02-06 23:26 UTC by jim at commercebyte dot com

Patch class_entry_gone_before_dtor for Class/Object related Bug #74053

Patch version 2017-02-06 23:26 UTC

Return to Bug #74053 | Download this patch
Patch Revisions:

Developer: jim@commercebyte.com

diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c
index 858113a..a0de331 100644
--- a/Zend/zend_objects_API.c
+++ b/Zend/zend_objects_API.c
@@ -32,6 +32,7 @@ ZEND_API void zend_objects_store_init(zend_objects_store *objects, uint32_t init
 	objects->top = 1; /* Skip 0 so that handles are true */
 	objects->size = init_size;
 	objects->free_list_head = -1;
+	objects->no_reuse = 0;
 	memset(&objects->object_buckets[0], 0, sizeof(zend_object*));
 }
 
@@ -43,6 +44,7 @@ ZEND_API void zend_objects_store_destroy(zend_objects_store *objects)
 
 ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects)
 {
+	objects->no_reuse = 1; /* new objects spawned by dtors will never reuse unused slots, so their own dtors will be called further down the loop */
 	if (objects->top > 1) {
 		uint32_t i;
 		for (i = 1; i < objects->top; i++) {
@@ -111,7 +113,7 @@ ZEND_API void zend_objects_store_put(zend_object *object)
 {
 	int handle;
 
-	if (EG(objects_store).free_list_head != -1) {
+	if (!EG(objects_store).no_reuse && EG(objects_store).free_list_head != -1) {
 		handle = EG(objects_store).free_list_head;
 		EG(objects_store).free_list_head = GET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[handle]);
 	} else {
diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h
index 2230600..ebf0487 100644
--- a/Zend/zend_objects_API.h
+++ b/Zend/zend_objects_API.h
@@ -45,6 +45,7 @@ typedef struct _zend_objects_store {
 	uint32_t top;
 	uint32_t size;
 	int free_list_head;
+	char no_reuse; /* to be set to true when shutting down, to avoid missing dtor call on objects spawned by another dtor */
 } zend_objects_store;
 
 /* Global store handling functions */
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Fri Sep 30 00:03:42 2022 UTC