+
+zend_bool php_pq_callback_is_locked(php_pq_callback_t *cb TSRMLS_DC)
+{
+ if (cb->fci.size > 0 && Z_TYPE_P(cb->fci.function_name) == IS_OBJECT) {
+ const zend_function *closure = zend_get_closure_method_def(cb->fci.function_name TSRMLS_CC);
+
+ if (closure->type == ZEND_USER_FUNCTION) {
+ zend_execute_data *ex = EG(current_execute_data);
+
+ while (ex) {
+ if (ex->op_array == &closure->op_array) {
+ return 1;
+ }
+ ex = ex->prev_execute_data;
+ }
+ }
+ }
+ return 0;
+}
+
+void php_pq_callback_recurse(php_pq_callback_t *old, php_pq_callback_t *new TSRMLS_DC)
+{
+ if (new && new->fci.size > 0 && php_pq_callback_is_locked(old TSRMLS_CC)) {
+ new->recursion = emalloc(sizeof(*old));
+ memcpy(new->recursion, old, sizeof(*old));
+ } else if (new && new->fci.size > 0) {
+ php_pq_callback_dtor(old);
+ php_pq_callback_addref(new);
+ memcpy(old, new, sizeof(*old));
+ new->fci.size = 0;
+ } else {
+ php_pq_callback_dtor(old);
+ }
+}
+