diff options
| author | Wez Furlong <wez@php.net> | 2003-05-20 00:21:57 +0000 |
|---|---|---|
| committer | Wez Furlong <wez@php.net> | 2003-05-20 00:21:57 +0000 |
| commit | 1a6d970f7edab45b882a5a158b82f3eab127a352 (patch) | |
| tree | b1b5bc4f5eabe57fdc822860f9bfbd1f817732ba | |
| parent | 75144252c0d2adbdf7c5fca51ef4a3634d0590e9 (diff) | |
| download | php-git-1a6d970f7edab45b882a5a158b82f3eab127a352.tar.gz | |
Much better fix for refcount issues with contexts, and fix a leak in context
value storage.
| -rw-r--r-- | ext/standard/file.c | 3 | ||||
| -rw-r--r-- | ext/standard/fsock.c | 2 | ||||
| -rwxr-xr-x | 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() |
