]> granicus.if.org Git - php/commitdiff
Bug #47243 (Crash at shutdown on Windows)
authorChristopher Jones <sixd@php.net>
Mon, 9 Mar 2009 20:07:39 +0000 (20:07 +0000)
committerChristopher Jones <sixd@php.net>
Mon, 9 Mar 2009 20:07:39 +0000 (20:07 +0000)
ext/oci8/oci8.c
ext/oci8/php_oci8_int.h
ext/oci8/tests/b47243_1.phpt [new file with mode: 0644]
ext/oci8/tests/b47243_2.phpt [new file with mode: 0644]
ext/oci8/tests/b47243_3.phpt [new file with mode: 0644]
ext/oci8/tests/debug.phpt

index ee650db7f9e39d799556f6bf61980a490e0b8270..7bafe568bc5fd7a598179f4810296a5e4b5a014e 100644 (file)
 
 #if HAVE_OCI8
 
+#if PHP_MAJOR_VERSION < 6
+#error This version of the PHP OCI8 extension is not compatible with PHP 5 or earlier
+#endif
+
 #include "php_oci8.h"
 #include "php_oci8_int.h"
 #include "zend_hash.h"
 
 ZEND_DECLARE_MODULE_GLOBALS(oci)
 static PHP_GINIT_FUNCTION(oci);
+static PHP_GSHUTDOWN_FUNCTION(oci);
 
 /* True globals, no need for thread safety */
 int le_connection;
@@ -88,9 +93,6 @@ static void php_oci_spool_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC);
 static void php_oci_collection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC);
 
 static int php_oci_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC);
-#ifdef ZTS
-static int php_oci_list_helper(zend_rsrc_list_entry *le, void *le_type TSRMLS_DC);
-#endif
 static int php_oci_connection_ping(php_oci_connection * TSRMLS_DC);
 static int php_oci_connection_status(php_oci_connection * TSRMLS_DC);
 static int php_oci_connection_close(php_oci_connection * TSRMLS_DC);
@@ -813,7 +815,7 @@ zend_module_entry oci8_module_entry = {
        PHP_OCI8_VERSION,
        PHP_MODULE_GLOBALS(oci),  /* globals descriptor */
        PHP_GINIT(oci),                   /* globals ctor */
-       NULL,                                     /* globals dtor */
+       PHP_GSHUTDOWN(oci),               /* globals dtor */
        NULL,                                     /* post deactivate */
        STANDARD_MODULE_PROPERTIES_EX
 };
@@ -932,6 +934,16 @@ static PHP_GINIT_FUNCTION(oci)
 }
 /* }}} */
 
+/* {{{ PHP_GSHUTDOWN_FUNCTION
+ *
+ * Called for thread shutdown in ZTS, after module shutdown for non-ZTS
+ */
+static PHP_GSHUTDOWN_FUNCTION(oci)
+{
+       php_oci_cleanup_global_handles(TSRMLS_C);
+}
+/* }}} */
+
 PHP_MINIT_FUNCTION(oci)
 {
        zend_class_entry oci_lob_class_entry;
@@ -1051,36 +1063,17 @@ PHP_MSHUTDOWN_FUNCTION(oci)
 
        UNREGISTER_INI_ENTRIES();
 
-#ifndef ZTS
-       php_oci_cleanup_global_handles(TSRMLS_C);
-#endif
-
        return SUCCESS;
 }
 
 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);
-       while (OCI_G(num_statements) > 0) {
-               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. If persistent_helper is
         * unable to process a pconnection because of a refcount, the processing would happen from
         * np-destructor which is called when refcount goes to zero - php_oci_pconnection_list_np_dtor
         */
        zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper TSRMLS_CC);
 
-#ifdef ZTS
-       while (OCI_G(num_links) > OCI_G(num_persistent)) {
-               zend_hash_apply_with_argument(&EG(regular_list), (apply_func_arg_t) php_oci_list_helper, (void *)le_connection TSRMLS_CC);
-       }
-       php_oci_cleanup_global_handles(TSRMLS_C);
-#endif
-
        return SUCCESS;
 }
 
@@ -3017,24 +3010,6 @@ static sword php_oci_ping_init(php_oci_connection *connection, OCIError *errh TS
        return OCI_SUCCESS;
 } /* }}} */
 
-#ifdef ZTS
-/* {{{ php_oci_list_helper()
- *
- * Helper function to destroy data on thread shutdown in ZTS mode
- */
-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 && --le->refcount<=0) {
-                       return ZEND_HASH_APPLY_REMOVE;
-               }
-       }
-       return ZEND_HASH_APPLY_KEEP;
-} /* }}} */
-#endif
-
 #endif /* HAVE_OCI8 */
 
 /*
index d42f823864e7ca393cd3d06f858fa13eff82b797..55aa1f3ca3075adb08db21d11e98640ed44875b0 100644 (file)
@@ -329,7 +329,7 @@ typedef struct { /* php_oci_out_column {{{ */
        } while (0)
 
 #define PHP_OCI_ZVAL_TO_CONNECTION(zval, connection) \
-       ZEND_FETCH_RESOURCE2(connection, php_oci_connection *, &zval, -1, "oci8 connection", le_connection, le_pconnection);
+       ZEND_FETCH_RESOURCE2(connection, php_oci_connection *, &zval, -1, "oci8 connection", le_connection, le_pconnection)
 
 #define PHP_OCI_ZVAL_TO_STATEMENT(zval, statement) \
        ZEND_FETCH_RESOURCE(statement, php_oci_statement *, &zval, -1, "oci8 statement", le_statement)
diff --git a/ext/oci8/tests/b47243_1.phpt b/ext/oci8/tests/b47243_1.phpt
new file mode 100644 (file)
index 0000000..9f04f30
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+Bug #47243 (Crash on exit with ZTS mode)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die ("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+require(dirname(__FILE__).'/connect.inc');
+
+// Run Test
+
+$s = oci_parse($c, "select cursor(select dummy from dual) from dual");
+oci_execute($s);
+oci_fetch_all($s, $r);
+
+// No explicit free or close
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+===DONE===
diff --git a/ext/oci8/tests/b47243_2.phpt b/ext/oci8/tests/b47243_2.phpt
new file mode 100644 (file)
index 0000000..08f5f52
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+Bug #47243 (Crash on exit with ZTS mode)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die ("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+require(dirname(__FILE__).'/connect.inc');
+
+// Run Test
+
+$s = oci_parse($c, "select cursor(select dummy from dual) from dual");
+oci_execute($s);
+oci_fetch_all($s, $r);
+
+oci_free_statement($s);
+// no explicit close
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+===DONE===
diff --git a/ext/oci8/tests/b47243_3.phpt b/ext/oci8/tests/b47243_3.phpt
new file mode 100644 (file)
index 0000000..0decb34
--- /dev/null
@@ -0,0 +1,24 @@
+--TEST--
+Bug #47243 (Crash on exit with ZTS mode)
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die ("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+require(dirname(__FILE__).'/connect.inc');
+
+// Run Test
+
+$s = oci_parse($c, "select cursor(select dummy from dual) from dual");
+oci_execute($s);
+oci_fetch_all($s, $r);
+
+// With explicit free and close
+oci_free_statement($s);
+oci_close($c);
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+===DONE===
index deed632eafc1246609be9e598b54be61bf5b7405..91bd7779fe4475ef780cbf946b17e4e0005cb965 100644 (file)
@@ -29,7 +29,6 @@ echo "Done\n";
 
 ?>
 --EXPECTF--
-OCI8 DEBUG: OCINlsEnvironmentVariableGet at (%s:%d) 
 OCI8 DEBUG L1: Got NO cached connection at (%s:%d) 
 OCI8 DEBUG: OCIEnvNlsCreate at (%s:%d) 
 OCI8 DEBUG: OCIHandleAlloc at (%s:%d) 
@@ -59,3 +58,9 @@ OCI8 DEBUG: OCISessionRelease at (%s:%d)
 OCI8 DEBUG: OCIHandleFree at (%s:%d) 
 OCI8 DEBUG: OCIHandleFree at (%s:%d) 
 Done
+OCI8 DEBUG: OCISessionPoolDestroy at (%s:%d) 
+OCI8 DEBUG: OCIHandleFree at (%s:%d) 
+OCI8 DEBUG: OCIHandleFree at (%s:%d) 
+OCI8 DEBUG: OCIHandleFree at (%s:%d) 
+OCI8 DEBUG: OCIHandleFree at (%s:%d) 
+OCI8 DEBUG: OCIHandleFree at (%s:%d)