]> granicus.if.org Git - php/commitdiff
fix segfault in ZTS mode when statements containing sub-statements are destroyed...
authorAntony Dovgal <tony2001@php.net>
Fri, 10 Nov 2006 16:33:28 +0000 (16:33 +0000)
committerAntony Dovgal <tony2001@php.net>
Fri, 10 Nov 2006 16:33:28 +0000 (16:33 +0000)
ext/oci8/oci8.c
ext/oci8/oci8_statement.c
ext/oci8/php_oci8_int.h

index 0956504a32a97ce4ad4162cb66c09271a5c435b5..39e3c28ee37b559ba72f0f199af6872bedc9b805 100644 (file)
@@ -647,7 +647,9 @@ PHP_RSHUTDOWN_FUNCTION(oci)
 #ifdef ZTS
        zend_hash_apply_with_argument(&EG(regular_list), (apply_func_arg_t) php_oci_list_helper, (void *)le_descriptor TSRMLS_CC);
        zend_hash_apply_with_argument(&EG(regular_list), (apply_func_arg_t) php_oci_list_helper, (void *)le_collection TSRMLS_CC);
-       zend_hash_apply_with_argument(&EG(regular_list), (apply_func_arg_t) php_oci_list_helper, (void *)le_statement TSRMLS_CC);
+       while (OCI_G(num_statements)) { 
+               zend_hash_apply_with_argument(&EG(regular_list), (apply_func_arg_t) php_oci_list_helper, (void *)le_statement TSRMLS_CC);
+       }
 #endif
 
        /* check persistent connections and do the necessary actions if needed */
@@ -1810,13 +1812,13 @@ static int php_oci_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC)
 static int php_oci_list_helper(zend_rsrc_list_entry *le, void *le_type TSRMLS_DC)
 {
        int type = (int) le_type;
-               
+
        if (le->type == type) {
-               if (le->ptr != NULL) {
-                       return 1;
+               if (le->ptr != NULL && --le->refcount<=0) {
+                       return ZEND_HASH_APPLY_REMOVE;
                }
        }
-       return 0;
+       return ZEND_HASH_APPLY_KEEP;
 } /* }}} */
 #endif
 
index 2e412a871310125f33a68387b0be34deb6fab16d..8c117ea304eb251295b129e00d34f002d4336739 100644 (file)
@@ -113,6 +113,8 @@ php_oci_statement *php_oci_statement_create (php_oci_connection *connection, cha
        }
        
        PHP_OCI_REGISTER_RESOURCE(statement, le_statement);
+
+       OCI_G(num_statements)++;
        
        return statement;
 }
@@ -520,6 +522,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC)
                                        outcol->retlen = -1;
                                        dynamic = OCI_DEFAULT;
                                        buf = &(outcol->statement->stmt);
+                                       zend_list_addref(statement->id);
                                        break;
 
                                case SQLT_RDD:   /* ROWID */
@@ -694,6 +697,8 @@ void php_oci_statement_free(php_oci_statement *statement TSRMLS_DC)
        
        zend_list_delete(statement->connection->rsrc_id);
        efree(statement);
+       
+       OCI_G(num_statements)--;
 } /* }}} */
 
 /* {{{ php_oci_bind_pre_exec() 
index 65020b8c3169b3f23b3a9c9a31c546a7057b3da4..22d7f8c37ae53e5bbc2cb20471572c2394b16098 100644 (file)
@@ -411,6 +411,7 @@ ZEND_BEGIN_MODULE_GLOBALS(oci) /* {{{ */
        long max_persistent;    /* maximum number of persistent connections per process */
        long num_persistent;    /* number of existing persistent connections */
        long num_links;                 /* non-persistent + persistent connections */
+       long num_statements;    /* number of statements open */
        long ping_interval;             /* time interval between pings */
        long persistent_timeout;        /* time period after which idle persistent connection is considered expired */
        long statement_cache_size;      /* statement cache size. used with 9i+ clients only*/