summaryrefslogtreecommitdiff
path: root/ext/interbase/ibase_events.c
diff options
context:
space:
mode:
authorArd Biesheuvel <abies@php.net>2004-04-05 13:22:34 +0000
committerArd Biesheuvel <abies@php.net>2004-04-05 13:22:34 +0000
commit18fa461119ca339b0a3be0c1ec1ea6651febf502 (patch)
tree44fc36f2c8be61c9d06cb8bc16e7174a3d1c7129 /ext/interbase/ibase_events.c
parentf9c5fc6ecb40b7469b68b73b16a31ceedc88723b (diff)
downloadphp-git-18fa461119ca339b0a3be0c1ec1ea6651febf502.tar.gz
More divide & conquer
Diffstat (limited to 'ext/interbase/ibase_events.c')
-rw-r--r--ext/interbase/ibase_events.c137
1 files changed, 95 insertions, 42 deletions
diff --git a/ext/interbase/ibase_events.c b/ext/interbase/ibase_events.c
index a5361964a5..dc8fab36a4 100644
--- a/ext/interbase/ibase_events.c
+++ b/ext/interbase/ibase_events.c
@@ -29,13 +29,66 @@
#include "php_interbase.h"
#include "php_ibase_includes.h"
-void _php_ibase_event_free(char *event_buf, char *result_buf) /* {{{ */
+static int le_event;
+
+static void _php_ibase_event_free(char *event_buf, char *result_buf) /* {{{ */
{
isc_free(event_buf);
isc_free(result_buf);
}
/* }}} */
+PHPAPI 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)
{
@@ -43,7 +96,7 @@ static void _php_ibase_event_block(ibase_db_link *ib_link, unsigned short count,
unsigned long dummy_count[15];
/**
- * Unfortunately, there's no clean and portable way in C to pass arguments to
+ * 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)
@@ -52,8 +105,8 @@ static void _php_ibase_event_block(ibase_db_link *ib_link, unsigned short count,
* 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],
+ *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]);
/**
@@ -78,7 +131,7 @@ PHP_FUNCTION(ibase_wait_event)
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 */
@@ -102,8 +155,8 @@ PHP_FUNCTION(ibase_wait_event)
}
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]);
@@ -118,7 +171,7 @@ PHP_FUNCTION(ibase_wait_event)
_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) {
@@ -128,7 +181,7 @@ PHP_FUNCTION(ibase_wait_event)
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);
@@ -141,10 +194,10 @@ static isc_callback _php_ibase_callback(ibase_event *event, /* {{{ */
{
/* 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
+ * 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) {
@@ -155,16 +208,16 @@ static isc_callback _php_ibase_callback(ibase_event *event, /* {{{ */
default: /* == DEAD */
break;
case ACTIVE:
- args[0] = &event_name;
- args[1] = &link_id;
-
+ 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) {
@@ -172,24 +225,24 @@ static isc_callback _php_ibase_callback(ibase_event *event, /* {{{ */
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,
+ 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,
+ 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;
@@ -203,8 +256,8 @@ static isc_callback _php_ibase_callback(ibase_event *event, /* {{{ */
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
+ * 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.
*/
@@ -213,7 +266,7 @@ PHP_FUNCTION(ibase_set_event_handler)
ibase_event *event;
unsigned short i = 1, buffer_size;
int link_res_id;
-
+
RESET_ERRMSG;
/* no more than 15 events */
@@ -231,7 +284,7 @@ PHP_FUNCTION(ibase_set_event_handler)
cb_arg = args[1];
i = 2;
- ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, args[0], -1,
+ ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, args[0], -1,
"InterBase link", le_link, le_plink);
convert_to_long_ex(args[0]);
@@ -245,18 +298,18 @@ PHP_FUNCTION(ibase_set_event_handler)
cb_arg = args[0];
- ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link),
+ 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);
@@ -270,28 +323,28 @@ PHP_FUNCTION(ibase_set_event_handler)
*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,
+ _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,
+ 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));
}
@@ -302,14 +355,14 @@ PHP_FUNCTION(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));
@@ -317,7 +370,7 @@ PHP_FUNCTION(ibase_free_event_handler)
} else {
RETURN_FALSE;
}
-}
+}
/* }}} */
#endif /* HAVE_IBASE */