diff options
Diffstat (limited to 'ext/interbase/ibase_events.c')
-rw-r--r-- | ext/interbase/ibase_events.c | 385 |
1 files changed, 0 insertions, 385 deletions
diff --git a/ext/interbase/ibase_events.c b/ext/interbase/ibase_events.c deleted file mode 100644 index c8b59ebe12..0000000000 --- a/ext/interbase/ibase_events.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2005 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 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_0.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: Ard Biesheuvel <a.k.biesheuvel@its.tudelft.nl> | - +----------------------------------------------------------------------+ - */ - -/* $Id$ */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php.h" - -#if HAVE_IBASE - -#include "php_interbase.h" -#include "php_ibase_includes.h" - -static int le_event; - -static void _php_ibase_event_free(char *event_buf, char *result_buf) /* {{{ */ -{ - isc_free(event_buf); - isc_free(result_buf); -} -/* }}} */ - -void _php_ibase_free_event(ibase_event *event TSRMLS_DC) /* {{{ */ -{ - unsigned short i; - - event->state = DEAD; - - if (event->link != NULL) { - ibase_event **node; - - if (event->link->handle != NULL && - isc_cancel_events(IB_STATUS, &event->link->handle, &event->event_id)) { - _php_ibase_error(TSRMLS_C); - } - - /* delete this event from the link struct */ - for (node = &event->link->event_head; *node != event; node = &(*node)->event_next); - *node = event->event_next; - } - - if (event->callback) { - zval_dtor(event->callback); - FREE_ZVAL(event->callback); - event->callback = NULL; - - _php_ibase_event_free(event->event_buffer,event->result_buffer); - - for (i = 0; i < event->event_count; ++i) { - efree(event->events[i]); - } - efree(event->events); - } -} -/* }}} */ - -static void _php_ibase_free_event_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ -{ - ibase_event *e = (ibase_event *) rsrc->ptr; - - _php_ibase_free_event(e TSRMLS_CC); - - efree(e); -} -/* }}} */ - -void php_ibase_events_minit(INIT_FUNC_ARGS) /* {{{ */ -{ - le_event = zend_register_list_destructors_ex(_php_ibase_free_event_rsrc, NULL, - "interbase event", module_number); -} -/* }}} */ - -static void _php_ibase_event_block(ibase_db_link *ib_link, unsigned short count, /* {{{ */ - char **events, unsigned short *l, char **event_buf, char **result_buf) -{ - ISC_STATUS dummy_result[20]; - unsigned long dummy_count[15]; - - /** - * Unfortunately, there's no clean and portable way in C to pass arguments to - * a variadic function if you don't know the number of arguments at compile time. - * (And even if there were a way, the Interbase API doesn't provide a version of - * this function that takes a va_list as an argument) - * - * In this case, the number of arguments is limited to 18 by the underlying API, - * so we can work around it. - */ - - *l = (unsigned short) isc_event_block(event_buf, result_buf, count, events[0], - events[1], events[2], events[3], events[4], events[5], events[6], events[7], - events[8], events[9], events[10], events[11], events[12], events[13], events[14]); - - /** - * Currently, this is the only way to correctly initialize an event buffer. - * This is clearly something that should be fixed, cause the semantics of - * isc_wait_for_event() indicate that it blocks until an event occurs. - * If the Firebird people ever fix this, these lines should be removed, - * otherwise, events will have to fire twice before ibase_wait_event() returns. - */ - - isc_wait_for_event(dummy_result, &ib_link->handle, *l, *event_buf, *result_buf); - isc_event_counts(dummy_count, *l, *event_buf, *result_buf); -} -/* }}} */ - -/* {{{ proto string ibase_wait_event([resource link_identifier,] string event [, string event [, ...]]) - Waits for any one of the passed Interbase events to be posted by the database, and returns its name */ -PHP_FUNCTION(ibase_wait_event) -{ - zval **args[16]; - ibase_db_link *ib_link; - char *event_buffer, *result_buffer, *events[15]; - unsigned short i = 0, event_count = 0, buffer_size; - unsigned long occurred_event[15]; - - RESET_ERRMSG; - - /* no more than 15 events */ - if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 16) { - WRONG_PARAM_COUNT; - } - - if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) { - RETURN_FALSE; - } - - if (Z_TYPE_PP(args[0]) == IS_RESOURCE) { - - ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, args[0], -1, "InterBase link", le_link, le_plink); - i = 1; - - } else { - - if (ZEND_NUM_ARGS() > 15) { - WRONG_PARAM_COUNT; - } - - ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), "InterBase link", le_link, le_plink); - } - - for (; i < ZEND_NUM_ARGS(); ++i) { - convert_to_string_ex(args[i]); - events[event_count++] = Z_STRVAL_PP(args[i]); - } - - /* fills the required data structure with information about the events */ - _php_ibase_event_block(ib_link, event_count, events, &buffer_size, &event_buffer, &result_buffer); - - /* now block until an event occurs */ - if (isc_wait_for_event(IB_STATUS, &ib_link->handle, buffer_size, event_buffer, result_buffer)) { - _php_ibase_error(TSRMLS_C); - _php_ibase_event_free(event_buffer,result_buffer); - RETURN_FALSE; - } - - /* find out which event occurred */ - isc_event_counts(occurred_event, buffer_size, event_buffer, result_buffer); - for (i = 0; i < event_count; ++i) { - if (occurred_event[i]) { - char *result = estrdup(events[i]); - _php_ibase_event_free(event_buffer,result_buffer); - RETURN_STRING(result,0); - } - } - - /* If we reach this line, isc_wait_for_event() did return, but we don't know - which event fired. */ - _php_ibase_event_free(event_buffer,result_buffer); - RETURN_FALSE; -} -/* }}} */ - -static isc_callback _php_ibase_callback(ibase_event *event, /* {{{ */ - unsigned short buffer_size, char *result_buf) -{ - /* this function is called asynchronously by the Interbase client library. */ - TSRMLS_FETCH_FROM_CTX(event->thread_ctx); - - /** - * The callback function is called when the event is first registered and when the event - * is cancelled. I consider this is a bug. By clearing event->callback first and setting - * it to -1 later, we make sure nothing happens if no event was actually posted. - */ - switch (event->state) { - unsigned short i; - unsigned long occurred_event[15]; - zval event_name, link_id, return_value, *args[2]; - - default: /* == DEAD */ - break; - case ACTIVE: - args[0] = &event_name; - args[1] = &link_id; - - /* copy the updated results into the result buffer */ - memcpy(event->result_buffer, result_buf, buffer_size); - - INIT_ZVAL(event_name); - INIT_ZVAL(link_id); - ZVAL_RESOURCE(&link_id, event->link_res_id); - - /* find out which event occurred */ - isc_event_counts(occurred_event, buffer_size, event->event_buffer, event->result_buffer); - for (i = 0; i < event->event_count; ++i) { - if (occurred_event[i]) { - ZVAL_STRING(&event_name,event->events[i],0); - break; - } - } - - /* call the callback provided by the user */ - if (SUCCESS != call_user_function(EG(function_table), NULL, - event->callback, &return_value, 2, args TSRMLS_CC)) { - _php_ibase_module_error("Error calling callback %s" TSRMLS_CC, Z_STRVAL_P(event->callback)); - break; - } - - if (Z_TYPE(return_value) == IS_BOOL && !Z_BVAL(return_value)) { - event->state = DEAD; - break; - } - case NEW: - /* re-register the event */ - if (isc_que_events(IB_STATUS, &event->link->handle, &event->event_id, buffer_size, - event->event_buffer,(isc_callback)_php_ibase_callback, (void *)event)) { - - _php_ibase_error(TSRMLS_C); - } - event->state = ACTIVE; - } - return 0; -} -/* }}} */ - -/* {{{ proto resource ibase_set_event_handler([resource link_identifier,] callback handler, string event [, string event [, ...]]) - Register the callback for handling each of the named events */ -PHP_FUNCTION(ibase_set_event_handler) -{ - /** - * The callback passed to this function should take an event name (string) and a - * link resource id (int) as arguments. The value returned from the function is - * used to determine if the event handler should remain set. - */ - - zval **args[17], **cb_arg; - ibase_db_link *ib_link; - ibase_event *event; - unsigned short i = 1, buffer_size; - int link_res_id; - - RESET_ERRMSG; - - /* no more than 15 events */ - if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 17) { - WRONG_PARAM_COUNT; - } - - if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) { - RETURN_FALSE; - } - - /* get a working link */ - if (Z_TYPE_PP(args[0]) != IS_STRING) { - - cb_arg = args[1]; - i = 2; - - ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, args[0], -1, - "InterBase link", le_link, le_plink); - - convert_to_long_ex(args[0]); - link_res_id = Z_LVAL_PP(args[0]); - - } else { - - if (ZEND_NUM_ARGS() > 16) { - WRONG_PARAM_COUNT; - } - - cb_arg = args[0]; - - ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), - "InterBase link", le_link, le_plink); - link_res_id = IBG(default_link); - } - - /* get the callback */ - if (!zend_is_callable(*cb_arg, 0, NULL)) { - _php_ibase_module_error("Callback argument %s is not a callable function" - TSRMLS_CC, Z_STRVAL_PP(cb_arg)); - RETURN_FALSE; - } - - /* allocate the event resource */ - event = (ibase_event *) safe_emalloc(sizeof(ibase_event), 1, 0); - TSRMLS_SET_CTX(event->thread_ctx); - event->link_res_id = link_res_id; - event->link = ib_link; - event->event_count = 0; - event->state = NEW; - event->events = (char **) safe_emalloc(sizeof(char *),ZEND_NUM_ARGS()-i,0); - - ALLOC_ZVAL(event->callback); - *event->callback = **cb_arg; - INIT_PZVAL(event->callback); - zval_copy_ctor(event->callback); - - for (; i < ZEND_NUM_ARGS(); ++i) { - convert_to_string_ex(args[i]); - event->events[event->event_count++] = estrdup(Z_STRVAL_PP(args[i])); - } - - /* fills the required data structure with information about the events */ - _php_ibase_event_block(ib_link, event->event_count, event->events, - &buffer_size, &event->event_buffer, &event->result_buffer); - - /* now register the events with the Interbase API */ - if (isc_que_events(IB_STATUS, &ib_link->handle, &event->event_id, buffer_size, - event->event_buffer,(isc_callback)_php_ibase_callback, (void *)event)) { - - _php_ibase_error(TSRMLS_C); - efree(event); - RETURN_FALSE; - } - - event->event_next = ib_link->event_head; - ib_link->event_head = event; - - ZEND_REGISTER_RESOURCE(return_value, event, le_event); - zend_list_addref(Z_LVAL_P(return_value)); -} -/* }}} */ - -/* {{{ proto bool ibase_free_event_handler(resource event) - Frees the event handler set by ibase_set_event_handler() */ -PHP_FUNCTION(ibase_free_event_handler) -{ - zval *event_arg; - - RESET_ERRMSG; - - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &event_arg)) { - ibase_event *event; - - ZEND_FETCH_RESOURCE(event, ibase_event *, &event_arg, -1, "Interbase event", le_event); - - event->state = DEAD; - - zend_list_delete(Z_LVAL_P(event_arg)); - RETURN_TRUE; - } else { - RETURN_FALSE; - } -} -/* }}} */ - -#endif /* HAVE_IBASE */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: sw=4 ts=4 fdm=marker - * vim<600: sw=4 ts=4 - */ |