summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2003-05-20 00:21:57 +0000
committerWez Furlong <wez@php.net>2003-05-20 00:21:57 +0000
commit1a6d970f7edab45b882a5a158b82f3eab127a352 (patch)
treeb1b5bc4f5eabe57fdc822860f9bfbd1f817732ba
parent75144252c0d2adbdf7c5fca51ef4a3634d0590e9 (diff)
downloadphp-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.c3
-rw-r--r--ext/standard/fsock.c2
-rwxr-xr-xmain/streams.c22
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()