/* +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Stig Sæther Bakken | | Thies C. Arntzen | | | | Collection support by Andy Sautins | | Temporary LOB support by David Benson | | ZTS per process OCIPLogon by Harald Radi | | | | Redesigned by: Antony Dovgal | | Andi Gutmans | | Wez Furlong | +----------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "ext/standard/info.h" #include "php_ini.h" #ifdef HAVE_OCI8 #include "php_oci8.h" #include "php_oci8_int.h" /* {{{ callback_fn() OCI TAF callback function, calling userspace function */ sb4 callback_fn(void *svchp, void *envhp, void *fo_ctx, ub4 fo_type, ub4 fo_event) { /* Create zval */ zval retval, params[3]; php_oci_connection *connection = (php_oci_connection*)fo_ctx; /* Default return value */ sb4 returnValue = 0; /* Check if userspace callback function was unregistered */ if (Z_ISUNDEF(connection->taf_callback) || Z_ISNULL(connection->taf_callback)) { return 0; } /* Initialize zval */ ZVAL_RES(¶ms[0], connection->id); ZVAL_LONG(¶ms[1], fo_event); ZVAL_LONG(¶ms[2], fo_type); /* Call user function (if possible) */ if (call_user_function(NULL, NULL, &connection->taf_callback, &retval, 3, params) == FAILURE) { php_error_docref(NULL, E_WARNING, "Unable to call Oracle TAF callback function"); } /* Set return value */ if (Z_TYPE(retval) == IS_LONG) { returnValue = (sb4) Z_LVAL(retval); } /* Setting params[0] to null so resource isn't destroyed on zval_ptr_dtor */ ZVAL_NULL(¶ms[0]); /* Cleanup */ zval_ptr_dtor(&retval); zval_ptr_dtor(¶ms[0]); zval_ptr_dtor(¶ms[1]); zval_ptr_dtor(¶ms[2]); return returnValue; } /* }}} */ /* {{{ php_oci_unregister_taf_callback() Unregister the userspace callback function for Oracle TAF, while keeping the OCI callback alive */ int php_oci_unregister_taf_callback(php_oci_connection *connection) { return php_oci_register_taf_callback(connection, NULL); } /* }}} */ /* {{{ php_oci_register_taf_callback() Register a callback function for Oracle TAF */ int php_oci_register_taf_callback(php_oci_connection *connection, zval *callback) { sword errstatus; int registered = 0; /* temporary failover callback structure */ OCIFocbkStruct failover; if (!callback) { /* Unregister callback */ if (Z_ISUNDEF(connection->taf_callback) || Z_ISNULL(connection->taf_callback)) { return 0; // Nothing to unregister } registered = 1; zval_ptr_dtor(&connection->taf_callback); ZVAL_NULL(&connection->taf_callback); } else { if (!Z_ISUNDEF(connection->taf_callback)) { registered = 1; if (!Z_ISNULL(connection->taf_callback)) { zval_ptr_dtor(&connection->taf_callback); ZVAL_NULL(&connection->taf_callback); } } /* Set userspace callback function */ ZVAL_COPY(&connection->taf_callback, callback); } /* OCI callback function already registered */ if (registered) { return 0; } /* set context */ failover.fo_ctx = connection; /* set callback function */ failover.callback_function = &callback_fn; /* do the registration */ PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, (connection->server, (ub4) OCI_HTYPE_SERVER, (void *) &failover, (ub4) 0, (ub4) OCI_ATTR_FOCBK, connection->err)); if (errstatus != OCI_SUCCESS) { zval_ptr_dtor(&connection->taf_callback); ZVAL_UNDEF(&connection->taf_callback); connection->errcode = php_oci_error(connection->err, errstatus); return 1; } /* successful conclusion */ return 0; } /* }}} */ #endif /* HAVE_OCI8 */