com php-src: Fixed nested GC calls (valgrind error in Zend/tests/gc_016.phpt): Zend/zend_gc.c
| From: | Dmitry Stogov | Date: | Mon, 14 Apr 2014 18:41:42 +0000 |
| Subject: | com php-src: Fixed nested GC calls (valgrind error in Zend/tests/gc_016.phpt): Zend/zend_gc.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-77406@lists.php.net to get a copy of this message | ||
Commit: b0b54e8db4d67dba3dec1bc1651f351d4762f984
Author: Dmitry Stogov <dmitry@zend.com> Mon, 14 Apr 2014 22:41:42 +0400
Parents: 703c1bc570d1fc9a379fa38b298d6759a4b1a687
Branches: phpng
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=b0b54e8db4d67dba3dec1bc1651f351d4762f984
Log:
Fixed nested GC calls (valgrind error in Zend/tests/gc_016.phpt)
Changed paths:
M Zend/zend_gc.c
Diff:
diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c
index ec72d1e..ea33122 100644
--- a/Zend/zend_gc.c
+++ b/Zend/zend_gc.c
@@ -612,6 +612,7 @@ ZEND_API int gc_collect_cycles(TSRMLS_D)
if (GC_G(roots).next != &GC_G(roots)) {
gc_root_buffer *current, *orig_next_to_free;
zend_refcounted *p;
+ gc_root_buffer to_free;
if (GC_G(gc_active)) {
return 0;
@@ -621,13 +622,28 @@ ZEND_API int gc_collect_cycles(TSRMLS_D)
gc_mark_roots(TSRMLS_C);
gc_scan_roots(TSRMLS_C);
count = gc_collect_roots(TSRMLS_C);
+ GC_G(gc_active) = 0;
+
+ if (GC_G(to_free).next == &GC_G(to_free)) {
+ /* nothing to free */
+ return 0;
+ }
+
+ /* Copy global to_free list into local list */
+ to_free.next = GC_G(to_free).next;
+ to_free.prev = GC_G(to_free).prev;
+ to_free.next->prev = &to_free;
+ to_free.prev->next = &to_free;
+
+ /* Free global list */
+ GC_G(to_free).next = &GC_G(to_free);
+ GC_G(to_free).prev = &GC_G(to_free);
orig_next_to_free = GC_G(next_to_free);
- GC_G(gc_active) = 0;
/* First call destructors */
- current = GC_G(to_free).next;
- while (current != &GC_G(to_free)) {
+ current = to_free.next;
+ while (current != &to_free) {
p = current->ref;
GC_G(next_to_free) = current->next;
if (GC_TYPE(p) == IS_OBJECT) {
@@ -649,8 +665,8 @@ ZEND_API int gc_collect_cycles(TSRMLS_D)
}
/* Destroy zvals */
- current = GC_G(to_free).next;
- while (current != &GC_G(to_free)) {
+ current = to_free.next;
+ while (current != &to_free) {
p = current->ref;
GC_G(next_to_free) = current->next;
if (GC_TYPE(p) == IS_OBJECT) {
@@ -677,8 +693,8 @@ ZEND_API int gc_collect_cycles(TSRMLS_D)
}
/* Free objects */
- current = GC_G(to_free).next;
- while (current != &GC_G(to_free)) {
+ current = to_free.next;
+ while (current != &to_free) {
p = current->ref;
GC_G(next_to_free) = current->next;
if (GC_TYPE(p) == IS_OBJECT) {