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
);
32 if (cb
->fci
.object_ptr
) {
33 zval_ptr_dtor(&cb
->fci
.object_ptr
);
39 void php_pq_callback_addref(php_pq_callback_t
*cb
)
41 Z_ADDREF_P(cb
->fci
.function_name
);
42 if (cb
->fci
.object_ptr
) {
43 Z_ADDREF_P(cb
->fci
.object_ptr
);
47 zval
*php_pq_callback_to_zval(php_pq_callback_t
*cb
)
51 php_pq_callback_addref(cb
);
53 if (cb
->fci
.object_ptr
) {
55 array_init_size(zcb
, 2);
56 add_next_index_zval(zcb
, cb
->fci
.object_ptr
);
57 add_next_index_zval(zcb
, cb
->fci
.function_name
);
59 zcb
= cb
->fci
.function_name
;
65 zend_bool
php_pq_callback_is_locked(php_pq_callback_t
*cb TSRMLS_DC
)
67 if (php_pq_callback_is_enabled(cb
)) {
68 const zend_function
*closure
;
69 const zend_execute_data
*ex
;
71 if (Z_TYPE_P(cb
->fci
.function_name
) != IS_OBJECT
) {
75 closure
= zend_get_closure_method_def(cb
->fci
.function_name TSRMLS_CC
);
76 if (closure
->type
!= ZEND_USER_FUNCTION
) {
80 for (ex
= EG(current_execute_data
); ex
; ex
= ex
->prev_execute_data
) {
81 if (ex
->op_array
== &closure
->op_array
) {
87 if (!php_pq_callback_is_recurrent(cb
)) {
90 return php_pq_callback_is_locked(cb
->recursion TSRMLS_CC
);
93 void php_pq_callback_recurse(php_pq_callback_t
*old
, php_pq_callback_t
*new TSRMLS_DC
)
95 if (php_pq_callback_is_locked(old TSRMLS_CC
)) {
96 php_pq_callback_recurse_ex(old
, new TSRMLS_CC
);
98 php_pq_callback_dtor(old
);
99 if (php_pq_callback_is_enabled(new)) {
100 php_pq_callback_addref(new);
101 memcpy(old
, new, sizeof(*old
));
107 extern zend_bool
php_pq_callback_is_enabled(php_pq_callback_t
*cb
)
109 return cb
&& cb
->fci
.size
> 0;
112 extern zend_bool
php_pq_callback_is_recurrent(php_pq_callback_t
*cb
)
114 return cb
&& cb
->recursion
!= NULL
;
117 extern void php_pq_callback_disable(php_pq_callback_t
*cb TSRMLS_DC
)
119 if (php_pq_callback_is_enabled(cb
)) {
120 php_pq_callback_recurse_ex(cb
, NULL TSRMLS_CC
);
124 extern void php_pq_callback_recurse_ex(php_pq_callback_t
*old
, php_pq_callback_t
*new TSRMLS_DC
)
126 php_pq_callback_t
*tmp
= emalloc(sizeof(*tmp
));
129 memcpy(tmp
, old
, sizeof(*tmp
));
130 memcpy(old
, new, sizeof(*old
));
131 old
->recursion
= tmp
;
133 php_pq_callback_addref(old
);
134 php_pq_callback_disable(tmp TSRMLS_CC
);
136 memcpy(tmp
, old
, sizeof(*tmp
));
137 memset(old
, 0, sizeof(*old
));
138 old
->recursion
= tmp
;
147 * vim600: noet sw=4 ts=4 fdm=marker
148 * vim<600: noet sw=4 ts=4