2 +--------------------------------------------------------------------+
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2013, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
18 #include <Zend/zend_closures.h>
20 #include "php_pq_callback.h"
22 void php_pq_callback_dtor(php_pq_callback_t
*cb
)
25 php_pq_callback_dtor(cb
->recursion
);
29 if (cb
->fci
.size
> 0) {
30 zend_fcall_info_args_clear(&cb
->fci
, 1);
31 zval_ptr_dtor(&cb
->fci
.function_name
);
35 ZVAL_OBJ(&tmp
, cb
->fci
.object
);
42 void php_pq_callback_addref(php_pq_callback_t
*cb
)
44 Z_TRY_ADDREF(cb
->fci
.function_name
);
47 GC_ADDREF(cb
->fci
.object
);
49 ++GC_REFCOUNT(cb
->fci
.object
);
54 zval
*php_pq_callback_to_zval(php_pq_callback_t
*cb
, zval
*tmp
)
56 php_pq_callback_addref(cb
);
61 array_init_size(tmp
, 2);
62 ZVAL_OBJ(&zo
, cb
->fci
.object
);
63 add_next_index_zval(tmp
, &zo
);
64 add_next_index_zval(tmp
, &cb
->fci
.function_name
);
69 return &cb
->fci
.function_name
;
72 zval
*php_pq_callback_to_zval_no_addref(php_pq_callback_t
*cb
, zval
*tmp
)
77 array_init_size(tmp
, 2);
78 ZVAL_OBJ(&zo
, cb
->fci
.object
);
79 add_next_index_zval(tmp
, &zo
);
80 add_next_index_zval(tmp
, &cb
->fci
.function_name
);
85 return &cb
->fci
.function_name
;
88 zend_bool
php_pq_callback_is_locked(php_pq_callback_t
*cb
)
90 /* TODO: fixed in php7?
91 if (php_pq_callback_is_enabled(cb)) {
92 const zend_function *closure;
93 const zend_execute_data *ex;
95 if (Z_TYPE_P(cb->fci.function_name) != IS_OBJECT) {
99 closure = zend_get_closure_method_def(cb->fci.function_name);
100 if (closure->type != ZEND_USER_FUNCTION) {
104 for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) {
105 if (ex->op_array == &closure->op_array) {
110 if (!php_pq_callback_is_recurrent(cb)) {
113 return php_pq_callback_is_locked(cb->recursion);
118 void php_pq_callback_recurse(php_pq_callback_t
*old
, php_pq_callback_t
*new)
120 if (php_pq_callback_is_locked(old
)) {
121 php_pq_callback_recurse_ex(old
, new);
123 php_pq_callback_dtor(old
);
124 if (php_pq_callback_is_enabled(new)) {
125 php_pq_callback_addref(new);
126 memcpy(old
, new, sizeof(*old
));
132 extern zend_bool
php_pq_callback_is_enabled(php_pq_callback_t
*cb
)
134 return cb
&& cb
->fci
.size
> 0;
137 extern zend_bool
php_pq_callback_is_recurrent(php_pq_callback_t
*cb
)
139 return cb
&& cb
->recursion
!= NULL
;
142 extern void php_pq_callback_disable(php_pq_callback_t
*cb
)
144 if (php_pq_callback_is_enabled(cb
)) {
145 php_pq_callback_recurse_ex(cb
, NULL
);
149 extern void php_pq_callback_recurse_ex(php_pq_callback_t
*old
, php_pq_callback_t
*new)
151 php_pq_callback_t
*tmp
= emalloc(sizeof(*tmp
));
154 memcpy(tmp
, old
, sizeof(*tmp
));
155 memcpy(old
, new, sizeof(*old
));
156 old
->recursion
= tmp
;
158 php_pq_callback_addref(old
);
159 php_pq_callback_disable(tmp
);
161 memcpy(tmp
, old
, sizeof(*tmp
));
162 memset(old
, 0, sizeof(*old
));
163 old
->recursion
= tmp
;
172 * vim600: noet sw=4 ts=4 fdm=marker
173 * vim<600: noet sw=4 ts=4