From 1a6d970f7edab45b882a5a158b82f3eab127a352 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Tue, 20 May 2003 00:21:57 +0000 Subject: [PATCH] Much better fix for refcount issues with contexts, and fix a leak in context value storage. --- ext/standard/file.c | 3 +-- ext/standard/fsock.c | 2 +- main/streams.c | 22 +++++++++++++++++++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/ext/standard/file.c b/ext/standard/file.c index bcde4a0c6d..4bbf1ce459 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -992,7 +992,6 @@ PHP_FUNCTION(stream_context_set_option) /* handle the array syntax */ RETVAL_BOOL(parse_context_options(context, options) == SUCCESS); } else { - ZVAL_ADDREF(zvalue); php_stream_context_set_option(context, wrappername, optionname, zvalue); RETVAL_TRUE; } @@ -1111,7 +1110,7 @@ PHP_NAMED_FUNCTION(php_if_fopen) php_stream_to_zval(stream, return_value); if (zcontext) { - ZVAL_ADDREF(zcontext); + zend_list_addref(Z_RESVAL_P(zcontext)); } } /* }}} */ diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c index 9a5a821c8e..cbae0aee51 100644 --- a/ext/standard/fsock.c +++ b/ext/standard/fsock.c @@ -281,7 +281,7 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent) } if (zcontext) { - ZVAL_ADDREF(zcontext); + zend_list_addref(Z_RESVAL_P(zcontext)); } php_stream_to_zval(stream, return_value); } diff --git a/main/streams.c b/main/streams.c index 0cb591ecef..bd87ddc01c 100755 --- a/main/streams.c +++ b/main/streams.c @@ -110,6 +110,15 @@ PHPAPI int php_file_le_pstream(void) return le_pstream; } +static int _php_stream_release_context(list_entry *le, void *pContext TSRMLS_DC) +{ + if (le->ptr == pContext) { + return --le->refcount == 0; + } + return 0; +} + + static int forget_persistent_resource_id_numbers(zend_rsrc_list_entry *rsrc TSRMLS_DC) { php_stream *stream; @@ -126,6 +135,9 @@ fprintf(stderr, "forget_persistent: %s:%p\n", stream->ops->label, stream); stream->rsrc_id = FAILURE; if (stream->context) { + zend_hash_apply_with_argument(&EG(regular_list), + (apply_func_arg_t) _php_stream_release_context, + stream->context TSRMLS_CC); stream->context = NULL; } @@ -2839,19 +2851,23 @@ PHPAPI int php_stream_context_set_option(php_stream_context *context, const char *wrappername, const char *optionname, zval *optionvalue) { zval **wrapperhash; - zval *category; + zval *category, *copied_val; + ALLOC_INIT_ZVAL(copied_val); + *copied_val = *optionvalue; + zval_copy_ctor(copied_val); + if (FAILURE == zend_hash_find(Z_ARRVAL_P(context->options), (char*)wrappername, strlen(wrappername)+1, (void**)&wrapperhash)) { MAKE_STD_ZVAL(category); array_init(category); + if (FAILURE == zend_hash_update(Z_ARRVAL_P(context->options), (char*)wrappername, strlen(wrappername)+1, (void**)&category, sizeof(zval *), NULL)) return FAILURE; - ZVAL_ADDREF(optionvalue); wrapperhash = &category; } - return zend_hash_update(Z_ARRVAL_PP(wrapperhash), (char*)optionname, strlen(optionname)+1, (void**)&optionvalue, sizeof(zval *), NULL); + return zend_hash_update(Z_ARRVAL_PP(wrapperhash), (char*)optionname, strlen(optionname)+1, (void**)&copied_val, sizeof(zval *), NULL); } PHPAPI HashTable *php_stream_get_url_stream_wrappers_hash() -- 2.50.1