From 0548ac59a5a87382f0daf4959047ecf564320093 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 27 Feb 2014 12:28:55 +0400 Subject: [PATCH] Resource closing without destruction --- Zend/zend_list.c | 70 +++++++++++++++++++++++++++++++----------- Zend/zend_list.h | 2 ++ main/streams/streams.c | 4 +-- 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) { -- 2.40.0