1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2020 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 #include "../src/common.h"
19 #include "../src/util.h"
20 #include "../src/priv.h"
21 #include "zend_exceptions.h"
22
23 /* {{{ proto EventBase EventBase::__construct([EventConfig cfg = null]); */
PHP_METHOD(EventBase,__construct)24 PHP_METHOD(EventBase, __construct)
25 {
26 php_event_base_t *b;
27 php_event_config_t *cfg;
28 zval *zcfg = NULL;
29
30 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O!",
31 &zcfg, php_event_config_ce) == FAILURE) {
32 return;
33 }
34
35 PHP_EVENT_FETCH_BASE(b, getThis());
36
37 if (zcfg == NULL) {
38 b->base = event_base_new();
39 } else {
40 PHP_EVENT_FETCH_CONFIG(cfg, zcfg);
41
42 b->base = event_base_new_with_config(cfg->ptr);
43 if (!b->base) {
44 zend_throw_exception_ex(php_event_get_exception(), 0 TSRMLS_CC,
45 "EventBase cannot be constructed with the provided configuration. "
46 "Make sure that the specified features are supported on the current platform.");
47 }
48 }
49 }
50 /* }}} */
51
52 /* {{{ proto int EventBase::__wakeup()
53 Prevents use of a EventBase instance that has been unserialized */
PHP_METHOD(EventBase,__wakeup)54 PHP_METHOD(EventBase, __wakeup)
55 {
56 zend_throw_exception_ex(php_event_get_exception(), 0 TSRMLS_CC, "EventBase instances are not serializable");
57 }
58 /* }}} */
59
60 /* {{{ proto int EventBase::__sleep()
61 Prevents serialization of a EventBase instance */
PHP_METHOD(EventBase,__sleep)62 PHP_METHOD(EventBase, __sleep)
63 {
64 zend_throw_exception_ex(php_event_get_exception(), 0 TSRMLS_CC, "EventBase instances are not serializable");
65 }
66 /* }}} */
67
68 /* {{{ proto void EventBase::free(void); */
PHP_METHOD(EventBase,free)69 PHP_METHOD(EventBase, free)
70 {
71 zval *zbase = getThis();
72 php_event_base_t *b;
73
74 if (zend_parse_parameters_none() == FAILURE) {
75 return;
76 }
77
78 PHP_EVENT_FETCH_BASE(b, zbase);
79
80 if (b->base) {
81 event_base_free(b->base);
82 b->base=NULL;
83 }
84 }
85 /* }}} */
86
87 /* {{{ proto string EventBase::getMethod(void);
88 * Returns event method in use. */
PHP_METHOD(EventBase,getMethod)89 PHP_METHOD(EventBase, getMethod)
90 {
91 zval *zbase = getThis();
92 php_event_base_t *b;
93
94 if (zend_parse_parameters_none() == FAILURE) {
95 return;
96 }
97
98 PHP_EVENT_FETCH_BASE(b, zbase);
99
100 RETURN_STRING((char *)event_base_get_method(b->base), 1);
101 }
102 /* }}} */
103
104 /* {{{ proto int EventBase::getFeatures(void);
105 * Returns bitmask of features supported. See EVENT_FEATURE_* constants. */
PHP_METHOD(EventBase,getFeatures)106 PHP_METHOD(EventBase, getFeatures)
107 {
108 zval *zbase = getThis();
109 php_event_base_t *b;
110
111 if (zend_parse_parameters_none() == FAILURE) {
112 return;
113 }
114
115 PHP_EVENT_FETCH_BASE(b, zbase);
116
117 RETVAL_LONG(event_base_get_features(b->base));
118 }
119 /* }}} */
120
121 /* {{{ proto bool EventBase::priorityInit(int n_priorities);
122 * Sets number of priorities per event base. Returns &true; on success, otherwise &false; */
PHP_METHOD(EventBase,priorityInit)123 PHP_METHOD(EventBase, priorityInit)
124 {
125 zval *zbase = getThis();
126 long n_priorities;
127 php_event_base_t *b;
128
129 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
130 &n_priorities) == FAILURE) {
131 return;
132 }
133
134 PHP_EVENT_FETCH_BASE(b, zbase);
135
136 if (event_base_priority_init(b->base, n_priorities)) {
137 RETURN_FALSE;
138 }
139 RETVAL_TRUE;
140 }
141 /* }}} */
142
143 /* {{{ proto bool EventBase::loop([int flags]);
144 * Wait for events to become active, and run their callbacks. */
PHP_METHOD(EventBase,loop)145 PHP_METHOD(EventBase, loop)
146 {
147 zval *zbase = getThis();
148 long flags = -1;
149 php_event_base_t *b;
150
151 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l",
152 &flags) == FAILURE) {
153 return;
154 }
155
156 PHP_EVENT_FETCH_BASE(b, zbase);
157
158 /* Call event_base_dispatch when flags omitted. */
159 if (flags == -1) {
160 if (event_base_dispatch(b->base) == -1) {
161 RETURN_FALSE;
162 }
163 } else if (event_base_loop(b->base, flags) == -1) {
164 RETURN_FALSE;
165 }
166
167 if (EG(exception)) {
168 zend_throw_exception_object(EG(exception) TSRMLS_CC);
169 }
170 /* Since 2.1.2-alpha we can call event_base_loopcontinue(b->base);*/
171
172 RETVAL_TRUE;
173 }
174 /* }}} */
175
176 /* {{{ proto bool EventBase::dispatch(void);
177 * Wait for events to become active, and run their callbacks.
178 * The same as EventBase::loop() with no flags set*/
PHP_METHOD(EventBase,dispatch)179 PHP_METHOD(EventBase, dispatch)
180 {
181 zval *zbase = getThis();
182 php_event_base_t *b;
183
184 if (zend_parse_parameters_none() == FAILURE) {
185 return;
186 }
187
188 PHP_EVENT_FETCH_BASE(b, zbase);
189
190 if (event_base_dispatch(b->base) == -1) {
191 RETURN_FALSE;
192 }
193
194 if (EG(exception)) {
195 zend_throw_exception_object(EG(exception) TSRMLS_CC);
196 }
197
198 RETVAL_TRUE;
199 }
200 /* }}} */
201
202 /* {{{ proto bool EventBase::exit([double timeout = 0.0]);
203 * Tells event_base to stop optionally after given number of seconds. */
PHP_METHOD(EventBase,exit)204 PHP_METHOD(EventBase, exit)
205 {
206 zval *zbase = getThis();
207 php_event_base_t *b;
208 double timeout = -1;
209 int res;
210
211 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|d",
212 &timeout) == FAILURE) {
213 return;
214 }
215
216 PHP_EVENT_FETCH_BASE(b, zbase);
217
218 if (timeout == -1) {
219 res = event_base_loopexit(b->base, NULL);
220 } else {
221 struct timeval tv;
222 PHP_EVENT_TIMEVAL_SET(tv, timeout);
223
224 res = event_base_loopexit(b->base, &tv);
225 }
226
227 if (res) {
228 RETURN_FALSE;
229 }
230 RETVAL_TRUE;
231 }
232 /* }}} */
233
234 /* {{{ proto bool EventBase::stop(void);
235 * Tells event_base to stop. */
PHP_METHOD(EventBase,stop)236 PHP_METHOD(EventBase, stop)
237 {
238 zval *zbase = getThis();
239 php_event_base_t *b;
240
241 if (zend_parse_parameters_none() == FAILURE) {
242 return;
243 }
244
245 PHP_EVENT_FETCH_BASE(b, zbase);
246
247 if (event_base_loopbreak(b->base)) {
248 RETURN_FALSE;
249 }
250 RETVAL_TRUE;
251 }
252 /* }}} */
253
254 /* {{{ proto bool EventBase::set(Event event);
255 * Associate event base with an event. */
PHP_METHOD(EventBase,set)256 PHP_METHOD(EventBase, set)
257 {
258 zval *zbase = getThis();
259 php_event_base_t *b;
260 zval *zevent;
261 php_event_t *e;
262
263 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O",
264 &zevent, php_event_ce) == FAILURE) {
265 return;
266 }
267
268 PHP_EVENT_FETCH_EVENT(e, zevent);
269
270 if (php_event_is_pending(e->event)) {
271 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't modify pending event");
272 RETURN_FALSE;
273 }
274
275 PHP_EVENT_FETCH_BASE(b, zbase);
276
277 if (event_base_set(b->base, e->event)) {
278 RETURN_FALSE;
279 }
280 RETVAL_TRUE;
281 }
282 /* }}} */
283
284 /* {{{ proto bool EventBase::gotStop(void);
285 *
286 * Checks if the event loop was told to abort immediately by EventBase::stop() */
PHP_METHOD(EventBase,gotStop)287 PHP_METHOD(EventBase, gotStop)
288 {
289 zval *zbase = getThis();
290 php_event_base_t *b;
291
292 if (zend_parse_parameters_none() == FAILURE) {
293 return;
294 }
295
296 PHP_EVENT_FETCH_BASE(b, zbase);
297
298 if (event_base_got_break(b->base)) {
299 RETURN_TRUE;
300 }
301 RETVAL_FALSE;
302 }
303 /* }}} */
304
305 /* {{{ proto bool EventBase::gotExit(void);
306 * Checks if the event loop was told to exit by EventBase::exit */
PHP_METHOD(EventBase,gotExit)307 PHP_METHOD(EventBase, gotExit)
308 {
309 zval *zbase = getThis();
310 php_event_base_t *b;
311
312 if (zend_parse_parameters_none() == FAILURE) {
313 return;
314 }
315
316 PHP_EVENT_FETCH_BASE(b, zbase);
317
318 if (event_base_got_exit(b->base)) {
319 RETURN_TRUE;
320 }
321 RETVAL_FALSE;
322 }
323 /* }}} */
324
325 /* {{{ proto double EventBase::getTimeOfDayCached(void);
326 *
327 * On success returns the current time(as returned by gettimeofday()), looking
328 * at the cached value in 'base' if possible, and calling gettimeofday() or
329 * clock_gettime() as appropriate if there is no cached time. On failure
330 * returns NULL. */
PHP_METHOD(EventBase,getTimeOfDayCached)331 PHP_METHOD(EventBase, getTimeOfDayCached)
332 {
333 zval *zbase = getThis();
334 php_event_base_t *b;
335 struct timeval tv;
336
337 if (zend_parse_parameters_none() == FAILURE) {
338 return;
339 }
340
341 PHP_EVENT_FETCH_BASE(b, zbase);
342
343 if (event_base_gettimeofday_cached(b->base, &tv)) {
344 RETURN_NULL();
345 }
346
347 RETVAL_DOUBLE(PHP_EVENT_TIMEVAL_TO_DOUBLE(tv));
348 }
349 /* }}} */
350
351 #if LIBEVENT_VERSION_NUMBER >= 0x02010100
352 /* {{{ proto bool EventBase::updateCacheTime(void);
353 * Updates cache time. Available since libevent 2.1.1-alpha */
PHP_METHOD(EventBase,updateCacheTime)354 PHP_METHOD(EventBase, updateCacheTime)
355 {
356 zval *zbase = getThis();
357 php_event_base_t *b;
358
359 if (zend_parse_parameters_none() == FAILURE) {
360 return;
361 }
362
363 PHP_EVENT_FETCH_BASE(b, zbase);
364
365 if (event_base_update_cache_time(b->base)) {
366 RETURN_FALSE;
367 }
368 RETVAL_TRUE;
369 }
370 /* }}} */
371 #endif
372
373 /* {{{ proto bool EventBase::reInit(void);
374 * Re-initialize event base. Should be called after a fork.
375 * XXX pthread_atfork() in MINIT */
PHP_METHOD(EventBase,reInit)376 PHP_METHOD(EventBase, reInit)
377 {
378 zval *zbase = getThis();
379 php_event_base_t *b;
380
381 if (zend_parse_parameters_none() == FAILURE) {
382 return;
383 }
384
385 PHP_EVENT_FETCH_BASE(b, zbase);
386
387 if (event_reinit(b->base)) {
388 RETURN_FALSE;
389 }
390
391 RETVAL_TRUE;
392 }
393 /* }}} */
394
395 #if LIBEVENT_VERSION_NUMBER >= 0x02010200
396 /* {{{ proto bool EventBase::resume(void);
397 * Tells event_base to resume previously stopped event.
398 * Available since libevent version 2.1.2-alpha. */
PHP_METHOD(EventBase,resume)399 PHP_METHOD(EventBase, resume)
400 {
401 zval *zbase = getThis();
402 php_event_base_t *b;
403
404 if (zend_parse_parameters_none() == FAILURE) {
405 return;
406 }
407
408 PHP_EVENT_FETCH_BASE(b, zbase);
409
410 if (event_base_loopcontinue(b->base)) {
411 RETURN_FALSE;
412 }
413 RETVAL_TRUE;
414 }
415 /* }}} */
416 #endif
417
418 /*
419 * Local variables:
420 * tab-width: 4
421 * c-basic-offset: 4
422 * End:
423 * vim600: noet sw=4 ts=4 sts=4 fdm=marker
424 * vim<600: noet sw=4 ts=4 sts=4
425 */
426