summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_list.c70
-rw-r--r--Zend/zend_list.h2
-rw-r--r--main/streams/streams.c4
3 files changed, 56 insertions, 20 deletions
diff --git a/Zend/zend_list.c b/Zend/zend_list.c
index 8bc5161bda..f7cbfac89f 100644
--- a/Zend/zend_list.c
+++ b/Zend/zend_list.c
@@ -50,6 +50,37 @@ ZEND_API int _zend_list_delete(zend_resource *res TSRMLS_DC)
}
}
+ZEND_API int _zend_list_close(zend_resource *res TSRMLS_DC)
+{
+ if (res->gc.refcount <= 0) {
+ return zend_list_delete(res);
+ } else if (res->type >= 0) {
+ zend_rsrc_list_dtors_entry *ld;
+
+ ld = zend_hash_index_find_ptr(&list_destructors, res->type);
+ if (ld) {
+ switch (ld->type) {
+ case ZEND_RESOURCE_LIST_TYPE_STD:
+ if (ld->list_dtor) {
+ (ld->list_dtor)(res->ptr);
+ }
+ break;
+ case ZEND_RESOURCE_LIST_TYPE_EX:
+ if (ld->list_dtor_ex) {
+ ld->list_dtor_ex(res TSRMLS_CC);
+ }
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ } else {
+ zend_error(E_WARNING,"Unknown list entry type in request shutdown (%d)", res->type);
+ }
+ res->ptr = NULL;
+ res->type = -1;
+ }
+ return SUCCESS;
+}
+
ZEND_API zend_resource* zend_register_resource(zval *rsrc_result, void *rsrc_pointer, int rsrc_type TSRMLS_DC)
{
zval *zv;
@@ -124,26 +155,29 @@ ZEND_API void *zend_fetch_resource(zval *passed_id TSRMLS_DC, int default_id, co
void list_entry_destructor(zval *zv)
{
zend_resource *res = Z_RES_P(zv);
- zend_rsrc_list_dtors_entry *ld;
- TSRMLS_FETCH();
+
+ if (res->type >= 0) {
+ zend_rsrc_list_dtors_entry *ld;
+ TSRMLS_FETCH();
- ld = zend_hash_index_find_ptr(&list_destructors, res->type);
- if (ld) {
- switch (ld->type) {
- case ZEND_RESOURCE_LIST_TYPE_STD:
- if (ld->list_dtor) {
- (ld->list_dtor)(res->ptr);
- }
- break;
- case ZEND_RESOURCE_LIST_TYPE_EX:
- if (ld->list_dtor_ex) {
- ld->list_dtor_ex(res TSRMLS_CC);
- }
- break;
- EMPTY_SWITCH_DEFAULT_CASE()
+ ld = zend_hash_index_find_ptr(&list_destructors, res->type);
+ if (ld) {
+ switch (ld->type) {
+ case ZEND_RESOURCE_LIST_TYPE_STD:
+ if (ld->list_dtor) {
+ (ld->list_dtor)(res->ptr);
+ }
+ break;
+ case ZEND_RESOURCE_LIST_TYPE_EX:
+ if (ld->list_dtor_ex) {
+ ld->list_dtor_ex(res TSRMLS_CC);
+ }
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ } else {
+ zend_error(E_WARNING,"Unknown list entry type in request shutdown (%d)", res->type);
}
- } else {
- zend_error(E_WARNING,"Unknown list entry type in request shutdown (%d)", res->type);
}
efree(res);
}
diff --git a/Zend/zend_list.h b/Zend/zend_list.h
index 52b171e422..c58905aa1f 100644
--- a/Zend/zend_list.h
+++ b/Zend/zend_list.h
@@ -66,8 +66,10 @@ void zend_destroy_rsrc_list_dtors(void);
ZEND_API zval *zend_list_insert(void *ptr, int type TSRMLS_DC);
ZEND_API int _zend_list_delete(zend_resource *res TSRMLS_DC);
+ZEND_API int _zend_list_close(zend_resource *res TSRMLS_DC);
#define zend_list_delete(res) _zend_list_delete(res TSRMLS_CC)
+#define zend_list_close(res) _zend_list_close(res TSRMLS_CC)
ZEND_API zend_resource *zend_register_resource(zval *rsrc_result, void *rsrc_pointer, int rsrc_type TSRMLS_DC);
ZEND_API void *zend_fetch_resource(zval *passed_id TSRMLS_DC, int default_id, const char *resource_type_name, int *found_resource_type, int num_resource_types, ...);
diff --git a/main/streams/streams.c b/main/streams/streams.c
index e80a87c860..c595c80240 100644
--- a/main/streams/streams.c
+++ b/main/streams/streams.c
@@ -464,8 +464,8 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov
* In any case, let's always completely delete it from the resource list,
* not only when PHP_STREAM_FREE_RELEASE_STREAM is set */
//??? while (zend_list_delete(stream->res) == SUCCESS) {}
- stream->res->gc.refcount = 0;
- zend_list_delete(stream->res);
+//??? stream->res->gc.refcount = 0;
+ zend_list_close(stream->res);
}
if (close_options & PHP_STREAM_FREE_CALL_DTOR) {