From 974b0ad2cdb8f19c7f599e443d9ec1b136ec1446 Mon Sep 17 00:00:00 2001 From: Antony Dovgal Date: Fri, 10 Nov 2006 16:33:28 +0000 Subject: [PATCH] fix segfault in ZTS mode when statements containing sub-statements are destroyed in wrong order --- ext/oci8/oci8.c | 12 +++++++----- ext/oci8/oci8_statement.c | 5 +++++ ext/oci8/php_oci8_int.h | 1 + 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index 0956504a32..39e3c28ee3 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -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 diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index 2e412a8713..8c117ea304 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -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() diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h index 65020b8c31..22d7f8c37a 100644 --- a/ext/oci8/php_oci8_int.h +++ b/ext/oci8/php_oci8_int.h @@ -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*/ -- 2.50.1