1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2021 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Ruslan Osmanov <osmanov@php.net> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* {{{ php_ev_loop_object_ctor
20 * Creates an instance of EvLoop class and puts it in retval
21 * in_ctor: whether called from constructor of a loop class
22 * default_loop: whether to return/create the default loop */
php_ev_loop_object_ctor(INTERNAL_FUNCTION_PARAMETERS,const zend_bool in_ctor,const zend_bool is_default_loop)23 static void php_ev_loop_object_ctor(INTERNAL_FUNCTION_PARAMETERS, const zend_bool in_ctor, const zend_bool is_default_loop)
24 {
25 php_ev_object *ev_obj;
26 ev_loop *loop;
27 zval **default_loop_ptr_ptr = NULL;
28
29 long flags = EVFLAG_AUTO;
30 double io_collect_interval = 0.;
31 double timeout_collect_interval = 0.;
32 zval *data = NULL;
33
34 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lz!dd",
35 &flags, &data,
36 &io_collect_interval, &timeout_collect_interval) == FAILURE) {
37 return;
38 }
39
40 default_loop_ptr_ptr = &MyG(default_loop);
41
42 if (!in_ctor) {
43 /* Factory method mode */
44 if (is_default_loop) {
45 if (!*default_loop_ptr_ptr) {
46 loop = ev_default_loop(flags);
47 } else {
48 RETURN_ZVAL(*default_loop_ptr_ptr, /* copy */ 1, /* dtor*/ 0);
49 }
50 } else {
51 loop = ev_loop_new(flags);
52 }
53
54 if (!loop) {
55 php_error_docref(NULL TSRMLS_CC, E_ERROR,
56 "Failed to instanciate default loop, "
57 "bad $LIBEV_FLAGS in environment?");
58 return;
59 }
60
61 PHP_EV_INIT_CLASS_OBJECT(return_value, ev_loop_class_entry_ptr);
62
63 ev_obj = (php_ev_object *) zend_object_store_get_object(return_value TSRMLS_CC);
64
65 /* Save return_value in MyG(default_loop) */
66 if (is_default_loop && !*default_loop_ptr_ptr) {
67 ALLOC_INIT_ZVAL(*default_loop_ptr_ptr);
68 REPLACE_ZVAL_VALUE(default_loop_ptr_ptr, return_value, 1);
69 }
70 } else {
71 /* Create custom event loop(OOP API) */
72 loop = ev_loop_new(flags);
73 if (!loop) {
74 php_error_docref(NULL TSRMLS_CC, E_ERROR,
75 "Failed to instanciate loop, bad backend, "
76 "or bad $LIBEV_FLAGS in environment?");
77 return;
78 }
79
80 ev_obj = (php_ev_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
81 }
82
83 php_ev_loop *ptr = (php_ev_loop *) emalloc(sizeof(php_ev_loop));
84 memset(ptr, 0, sizeof(php_ev_loop));
85 ptr->loop = loop;
86
87 if (data) {
88 Z_ADDREF_P(data);
89 }
90 ptr->data = data;
91 ptr->io_collect_interval = io_collect_interval;
92 ptr->timeout_collect_interval = timeout_collect_interval;
93 ev_obj->ptr = (void *) ptr;
94
95 ev_set_userdata(loop, (void *) (in_ctor ? getThis() : return_value));
96 }
97 /* }}} */
98
99 /* {{{ proto EvLoop EvLoop::defaultLoop([int flags = Ev::FLAG_AUTO[, mixed data = NULL[, double io_interval = 0.[, double timeout_interval = 0.]]]])
100 */
PHP_METHOD(EvLoop,defaultLoop)101 PHP_METHOD(EvLoop, defaultLoop)
102 {
103 php_ev_loop_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU,
104 /* in ctor */FALSE, /* is_default_loop */TRUE);
105 }
106 /* }}} */
107
108 /* {{{ proto EvLoop EvLoop::__construct([int flags = Ev::FLAG_AUTO[[, mixed data = NULL[, double io_interval = 0.[, double timeout_interval = 0.]]]]) */
PHP_METHOD(EvLoop,__construct)109 PHP_METHOD(EvLoop, __construct)
110 {
111 php_ev_loop_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU,
112 /* in ctor */TRUE, /* is_default_loop */FALSE);
113 }
114 /* }}} */
115
116
117 #define PHP_EV_LOOP_METHOD_VOID(name, evname) \
118 PHP_METHOD(EvLoop, name) \
119 { \
120 PHP_EV_LOOP_FETCH_FROM_THIS; \
121 \
122 if (zend_parse_parameters_none() == FAILURE) { \
123 return; \
124 } \
125 \
126 ev_ ## evname(EV_A); \
127 }
128
129 #define PHP_EV_LOOP_METHOD_INT_VOID(name, evname) \
130 PHP_METHOD(EvLoop, name) \
131 { \
132 PHP_EV_LOOP_FETCH_FROM_THIS; \
133 \
134 if (zend_parse_parameters_none() == FAILURE) { \
135 return; \
136 } \
137 \
138 RETURN_LONG(ev_ ## evname(EV_A)); \
139 }
140
PHP_EV_LOOP_METHOD_VOID(loopFork,loop_fork)141 PHP_EV_LOOP_METHOD_VOID(loopFork, loop_fork)
142 PHP_EV_LOOP_METHOD_VOID(verify, verify)
143 PHP_EV_LOOP_METHOD_VOID(invokePending, invoke_pending)
144 PHP_EV_LOOP_METHOD_VOID(nowUpdate, now_update)
145 PHP_EV_LOOP_METHOD_VOID(suspend, suspend)
146 PHP_EV_LOOP_METHOD_VOID(resume, resume)
147 PHP_EV_LOOP_METHOD_INT_VOID(backend, backend)
148
149 /* {{{ proto double EvLoop::now(void) */
150 PHP_METHOD(EvLoop, now)
151 {
152 PHP_EV_LOOP_FETCH_FROM_THIS;
153
154 if (zend_parse_parameters_none() == FAILURE) {
155 return;
156 }
157
158 RETURN_DOUBLE((double)ev_now(EV_A));
159 }
160 /* }}} */
161
162 /* {{{ proto void EvLoop::run([int flags = 0]) */
PHP_METHOD(EvLoop,run)163 PHP_METHOD(EvLoop, run)
164 {
165 PHP_EV_LOOP_FETCH_FROM_THIS;
166
167 long flags = 0;
168
169 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) == FAILURE) {
170 return;
171 }
172
173 ev_run(EV_A_ flags);
174 }
175 /* }}} */
176
177 /* {{{ proto void EvLoop::stop([int how = 0]) */
PHP_METHOD(EvLoop,stop)178 PHP_METHOD(EvLoop, stop)
179 {
180 PHP_EV_LOOP_FETCH_FROM_THIS;
181
182 long how = EVBREAK_ONE;
183
184 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &how) == FAILURE) {
185 return;
186 }
187
188 ev_break(EV_A_ how);
189 }
190 /* }}} */
191
192 /* {{{ proto EvIo EvLoop::io(mixed fd, int events, callable callback[, mixed data = NULL[, int priority = 0]]) */
PHP_METHOD(EvLoop,io)193 PHP_METHOD(EvLoop, io)
194 {
195 PHP_EV_WATCHER_FACTORY(io, getThis());
196 }
197 /* }}} */
198
199 /* {{{ proto EvTimer EvLoop::timer(double after, double repeat, EvLoop loop, callable callback[, mixed data = NULL[, int priority = 0]]) */
PHP_METHOD(EvLoop,timer)200 PHP_METHOD(EvLoop, timer)
201 {
202 PHP_EV_WATCHER_FACTORY(timer, getThis());
203 }
204 /* }}} */
205
206 #if EV_PERIODIC_ENABLE
207 /* {{{ proto EvPeriodic EvLoop::periodic(double offset, double interval, callable reschedule_cb, callable callback[, mixed data = NULL[, int priority = 0]]) */
PHP_METHOD(EvLoop,periodic)208 PHP_METHOD(EvLoop, periodic)
209 {
210 PHP_EV_WATCHER_FACTORY(periodic, getThis());
211 }
212 /* }}} */
213 #endif
214
215 #if EV_SIGNAL_ENABLE
216 /* {{{ proto EvSignal EvLoop::signal(int signum, callable callback[, mixed data = NULL[, int priority = 0]]) */
PHP_METHOD(EvLoop,signal)217 PHP_METHOD(EvLoop, signal)
218 {
219 PHP_EV_WATCHER_FACTORY(signal, getThis());
220 }
221 /* }}} */
222 #endif
223
224 #if EV_CHILD_ENABLE
225 /* {{{ proto EvChild EvLoop::child(int pid, bool trace, callable callback[, mixed data = NULL[, int priority = 0]]) */
PHP_METHOD(EvLoop,child)226 PHP_METHOD(EvLoop, child)
227 {
228 PHP_EV_WATCHER_FACTORY(child, getThis());
229 }
230 /* }}} */
231 #endif
232
233 #if EV_STAT_ENABLE
234 /* {{{ proto EvStat EvLoop::stat(string path, double interval, callable callback[, mixed data = NULL[, int priority = 0]]) */
PHP_METHOD(EvLoop,stat)235 PHP_METHOD(EvLoop, stat)
236 {
237 PHP_EV_WATCHER_FACTORY(stat, getThis());
238 }
239 /* }}} */
240 #endif
241
242 #if EV_IDLE_ENABLE
243 /* {{{ proto EvIdle EvLoop::idle(callable callback[, mixed data = NULL[, int priority = 0]]) */
PHP_METHOD(EvLoop,idle)244 PHP_METHOD(EvLoop, idle)
245 {
246 PHP_EV_WATCHER_FACTORY(idle, getThis());
247 }
248 /* }}} */
249 #endif
250
251 #if EV_CHECK_ENABLE
252 /* {{{ proto EvCheck EvLoop::check() */
PHP_METHOD(EvLoop,check)253 PHP_METHOD(EvLoop, check)
254 {
255 PHP_EV_WATCHER_FACTORY(check, getThis());
256 }
257 /* }}} */
258 #endif
259
260 #if EV_PREPARE_ENABLE
261 /* {{{ proto EvPrepare EvLoop::prepare() */
PHP_METHOD(EvLoop,prepare)262 PHP_METHOD(EvLoop, prepare)
263 {
264 PHP_EV_WATCHER_FACTORY(prepare, getThis());
265 }
266 /* }}} */
267 #endif
268
269 #if EV_EMBED_ENABLE
270 /* {{{ proto EvEmbed EvLoop::embed() */
PHP_METHOD(EvLoop,embed)271 PHP_METHOD(EvLoop, embed)
272 {
273 PHP_EV_WATCHER_FACTORY(embed, getThis());
274 }
275 /* }}} */
276 #endif
277
278 #if EV_FORK_ENABLE
279 /* {{{ proto EvFork EvLoop::fork() */
PHP_METHOD(EvLoop,fork)280 PHP_METHOD(EvLoop, fork)
281 {
282 PHP_EV_WATCHER_FACTORY(fork, getThis());
283 }
284 /* }}} */
285 #endif
286
287 /*
288 * Local variables:
289 * tab-width: 4
290 * c-basic-offset: 4
291 * End:
292 * vim600: noet sw=4 ts=4 sts=4 fdm=marker
293 * vim<600: noet sw=4 ts=4 sts=4
294 */
295