diff --git a/src/php_pq_callback.c b/src/php_pq_callback.c index 1f02a45..1a4a917 100644 --- a/src/php_pq_callback.c +++ b/src/php_pq_callback.c @@ -38,6 +38,23 @@ void php_pq_callback_addref(php_pq_callback_t *cb) } } +zval *php_pq_callback_to_zval(php_pq_callback_t *cb) +{ + zval *zcb; + + php_pq_callback_addref(cb); + + if (cb->fci.object_ptr) { + MAKE_STD_ZVAL(zcb); + array_init_size(zcb, 2); + add_next_index_zval(zcb, cb->fci.object_ptr); + add_next_index_zval(zcb, cb->fci.function_name); + } else { + zcb = cb->fci.function_name; + } + + return zcb; +} /* * Local variables: * tab-width: 4 diff --git a/src/php_pq_callback.h b/src/php_pq_callback.h index 14d8d80..4f2e85b 100644 --- a/src/php_pq_callback.h +++ b/src/php_pq_callback.h @@ -23,6 +23,7 @@ typedef struct php_pq_callback { void php_pq_callback_dtor(php_pq_callback_t *cb); void php_pq_callback_addref(php_pq_callback_t *cb); +zval *php_pq_callback_to_zval(php_pq_callback_t *cb); #endif diff --git a/src/php_pq_object.c b/src/php_pq_object.c index 704737f..c471edf 100644 --- a/src/php_pq_object.c +++ b/src/php_pq_object.c @@ -99,6 +99,13 @@ HashTable *php_pq_object_properties(zval *object TSRMLS_DC) return ht; } +HashTable *php_pq_object_gc(zval *object, zval ***gc_argv, int *gc_argc TSRMLS_DC) +{ + *gc_argv = NULL; + *gc_argc = 0; + return NULL; +} + zend_class_entry *ancestor(zend_class_entry *ce) { while (ce->parent) { diff --git a/src/php_pq_object.h b/src/php_pq_object.h index 311f17f..7498ffe 100644 --- a/src/php_pq_object.h +++ b/src/php_pq_object.h @@ -33,6 +33,7 @@ void php_pq_object_addref(void *o TSRMLS_DC); void php_pq_object_delref(void *o TSRMLS_DC); HashTable *php_pq_object_debug_info(zval *object, int *temp TSRMLS_DC); HashTable *php_pq_object_properties(zval *object TSRMLS_DC); +HashTable *php_pq_object_gc(zval *object, zval ***gc_argv, int *gc_argc TSRMLS_DC); zend_class_entry *ancestor(zend_class_entry *ce); zval *php_pq_object_read_prop(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC); void php_pq_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC); diff --git a/src/php_pqconn.c b/src/php_pqconn.c index 5031426..376ce3b 100644 --- a/src/php_pqconn.c +++ b/src/php_pqconn.c @@ -311,12 +311,40 @@ static void php_pqconn_object_read_options(zval *object, void *o, zval *return_v } } +static int apply_read_event_handler_ex(void *p, void *arg TSRMLS_DC) +{ + HashTable *rv = arg; + zval *zcb = php_pq_callback_to_zval(p); + + zend_hash_next_index_insert(rv, &zcb, sizeof(zval *), NULL); + + return ZEND_HASH_APPLY_KEEP; +} + +static int apply_read_event_handlers(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key) +{ + HashTable *evhs = p, *rv = va_arg(argv, HashTable *); + zval *entry, **entry_ptr; + + MAKE_STD_ZVAL(entry); + array_init_size(entry, zend_hash_num_elements(evhs)); + + if (key->nKeyLength) { + zend_hash_add(rv, key->arKey, key->nKeyLength, &entry, sizeof(zval *), (void *) &entry_ptr); + } else { + zend_hash_index_update(rv, key->h, &entry, sizeof(zval *), (void *) &entry_ptr); + } + + zend_hash_apply_with_argument(evhs, apply_read_event_handler_ex, Z_ARRVAL_PP(entry_ptr) TSRMLS_CC); + + return ZEND_HASH_APPLY_KEEP; +} static void php_pqconn_object_read_event_handlers(zval *object, void *o, zval *return_value TSRMLS_DC) { php_pqconn_object_t *obj = o; array_init(return_value); - zend_hash_copy(Z_ARRVAL_P(return_value), &obj->intern->eventhandlers, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); + zend_hash_apply_with_arguments(&obj->intern->eventhandlers TSRMLS_CC, apply_read_event_handlers, 1, Z_ARRVAL_P(return_value) TSRMLS_CC); } static STATUS php_pqconn_update_socket(zval *this_ptr, php_pqconn_object_t *obj TSRMLS_DC) @@ -1502,6 +1530,7 @@ PHP_MINIT_FUNCTION(pqconn) php_pqconn_object_handlers.write_property = php_pq_object_write_prop; php_pqconn_object_handlers.clone_obj = NULL; php_pqconn_object_handlers.get_property_ptr_ptr = NULL; + php_pqconn_object_handlers.get_gc = php_pq_object_gc; php_pqconn_object_handlers.get_properties = php_pq_object_properties; php_pqconn_object_handlers.get_debug_info = php_pq_object_debug_info;