summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-02-27 12:28:55 +0400
committerDmitry Stogov <dmitry@zend.com>2014-02-27 12:28:55 +0400
commit0548ac59a5a87382f0daf4959047ecf564320093 (patch)
tree7e5a29af2be917cd7b018191f2b008e83aaa740d /Zend
parent60eadc80b8b0a10a9498ae60571b9fb291e04b08 (diff)
downloadphp-git-0548ac59a5a87382f0daf4959047ecf564320093.tar.gz
Resource closing without destruction
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend_list.c70
-rw-r--r--Zend/zend_list.h2
2 files changed, 54 insertions, 18 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, ...);