]> granicus.if.org Git - php/commitdiff
Much better fix for refcount issues with contexts, and fix a leak in context
authorWez Furlong <wez@php.net>
Tue, 20 May 2003 00:21:57 +0000 (00:21 +0000)
committerWez Furlong <wez@php.net>
Tue, 20 May 2003 00:21:57 +0000 (00:21 +0000)
value storage.

ext/standard/file.c
ext/standard/fsock.c
main/streams.c

index bcde4a0c6dd9c7d9b0f6aacfe5a3f5fc861b97a5..4bbf1ce459bf6b3dec0a55cabd4ad5f4edf596b3 100644 (file)
@@ -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));
        }
 }
 /* }}} */
index 9a5a821c8ea5f6a8cc48c053747bd60ce9c1e5e6..cbae0aee5115ec2d4735053aa0f95189b01d4d5d 100644 (file)
@@ -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);
 }
index 0cb591ecef61837fb9a67e2fefe7a7155b8fd0fb..bd87ddc01cb2de4f62961f0e2ce81150ff6bde93 100755 (executable)
@@ -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()