123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- #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);
- }
-
- 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];
-
- *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]);
-
- isc_wait_for_event(dummy_result, &ib_link->handle, *l, *event_buf, *result_buf);
- isc_event_counts(dummy_count, *l, *event_buf, *result_buf);
- }
- PHP_FUNCTION(ibase_wait_event)
- {
- zval ***args;
- ibase_db_link *ib_link;
- int num_args;
- char *event_buffer, *result_buffer, *events[15];
- unsigned short i = 0, event_count = 0, buffer_size;
- unsigned long occurred_event[15];
- RESET_ERRMSG;
-
- if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 16) {
- WRONG_PARAM_COUNT;
- }
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &num_args) == FAILURE) {
- return;
- }
- if (Z_TYPE_PP(args[0]) == IS_RESOURCE) {
- if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, args[0], -1, "InterBase link", le_link, le_plink)) {
- efree(args);
- RETURN_FALSE;
- }
- i = 1;
- } else {
- if (ZEND_NUM_ARGS() > 15) {
- efree(args);
- WRONG_PARAM_COUNT;
- }
- if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, NULL, IBG(default_link), "InterBase link", le_link, le_plink)) {
- efree(args);
- RETURN_FALSE;
- }
- }
- for (; i < ZEND_NUM_ARGS(); ++i) {
- convert_to_string_ex(args[i]);
- events[event_count++] = Z_STRVAL_PP(args[i]);
- }
-
- _php_ibase_event_block(ib_link, event_count, events, &buffer_size, &event_buffer, &result_buffer);
-
- 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);
- efree(args);
- RETURN_FALSE;
- }
-
- 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);
- efree(args);
- RETURN_STRING(result,0);
- }
- }
-
- _php_ibase_event_free(event_buffer,result_buffer);
- efree(args);
- RETURN_FALSE;
- }
- static isc_callback _php_ibase_callback(ibase_event *event,
- unsigned short buffer_size, char *result_buf)
- {
-
- TSRMLS_FETCH_FROM_CTX(event->thread_ctx);
-
- switch (event->state) {
- unsigned short i;
- unsigned long occurred_event[15];
- zval event_name, link_id, return_value, *args[2];
- default:
- break;
- case ACTIVE:
- args[0] = &event_name;
- args[1] = &link_id;
-
- memcpy(event->result_buffer, result_buf, buffer_size);
- INIT_ZVAL(event_name);
- INIT_ZVAL(link_id);
- ZVAL_RESOURCE(&link_id, event->link_res_id);
-
- 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;
- }
- }
-
- 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:
-
- 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;
- }
- PHP_FUNCTION(ibase_set_event_handler)
- {
-
- char *cb_name;
- zval ***args, **cb_arg;
- ibase_db_link *ib_link;
- ibase_event *event;
- unsigned short i = 1, buffer_size;
- int link_res_id, num_args;
- RESET_ERRMSG;
-
-
- if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 17) {
- WRONG_PARAM_COUNT;
- }
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &num_args) == FAILURE) {
- return;
- }
-
- if (Z_TYPE_PP(args[0]) != IS_STRING) {
-
- if (ZEND_NUM_ARGS() < 3 || ZEND_NUM_ARGS() > 17) {
- efree(args);
- WRONG_PARAM_COUNT;
- }
- cb_arg = args[1];
- i = 2;
- if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, args[0], -1, "InterBase link", le_link, le_plink)) {
- efree(args);
- RETURN_FALSE;
- }
- convert_to_long_ex(args[0]);
- link_res_id = Z_LVAL_PP(args[0]);
- } else {
-
- if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 16) {
- efree(args);
- WRONG_PARAM_COUNT;
- }
- cb_arg = args[0];
- if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, NULL, IBG(default_link), "InterBase link", le_link, le_plink)) {
- efree(args);
- RETURN_FALSE;
- }
- link_res_id = IBG(default_link);
- }
-
- if (!zend_is_callable(*cb_arg, 0, &cb_name TSRMLS_CC)) {
- _php_ibase_module_error("Callback argument %s is not a callable function" TSRMLS_CC, cb_name);
- efree(cb_name);
- efree(args);
- RETURN_FALSE;
- }
- efree(cb_name);
-
- 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]));
- }
-
- _php_ibase_event_block(ib_link, event->event_count, event->events,
- &buffer_size, &event->event_buffer, &event->result_buffer);
-
- 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);
- efree(args);
- 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));
- efree(args);
- }
- 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
|