Пример #1
0
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);
}
Пример #2
0
static isc_callback _php_ibase_callback(ibase_event *event, /* {{{ */
	unsigned short buffer_size, char *result_buf)
{
	zval *res;

	/* 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 return_value, args[2];

		default: /* == DEAD */
			break;
		case ACTIVE:
			/* copy the updated results into the result buffer */
			memcpy(event->result_buffer, result_buf, buffer_size);

			res = zend_hash_index_find(&EG(regular_list), event->link_res_id);
			ZVAL_RES(&args[1], Z_RES_P(res));

			/* 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(&args[0], event->events[i]);
					efree(event->events[i]);
					break;
				}
			}

			/* call the callback provided by the user */
			if (SUCCESS != call_user_function(EG(function_table), NULL,
					&event->callback, &return_value, 2, args)) {
				_php_ibase_module_error("Error calling callback %s", Z_STRVAL(event->callback));
				break;
			}

			if (Z_TYPE(return_value) == IS_FALSE) {
				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();
			}
			event->state = ACTIVE;
	}
	return 0;
}
Пример #3
0
EXPORT RM_ENTRY(rmc_event_counts)
{
	ClearParamPool();
	ISC_STATUS *stat = AllocStatusPool();
	isc_event_counts((ISC_ULONG *)stat,
					 (short)*CobolToShort(&arg_vector[1]),
					 (ISC_UCHAR *)*(char **)arg_vector[2].a_address,
					 (ISC_UCHAR *)*(char **)arg_vector[3].a_address);
	// Convert the event counts to Cobol format.
	ISC_UCHAR *counts = (ISC_UCHAR *)arg_vector[0].a_address;
	ISC_UCHAR *cend = counts + arg_vector[0].a_length;
	int i = 0;
	while ((counts < cend) && (i < 15))
	{
		CvtIntToCobol(counts, stat[i], sizeof(ISC_ULONG));
		counts += sizeof(ISC_ULONG);
		i++;
	}

	return (0);
}
Пример #4
0
void API_ROUTINE gds__event_counts(ULONG* result_vector,
								   SSHORT length,
								   UCHAR* before, const UCHAR* after)
{
	isc_event_counts(result_vector, length, before, after);
}