[packages] php5: PECL: include support for libevent
[openwrt/svn-archive/archive.git] / lang / php5 / patches / 020-PECL-add-libevent.patch
1 --- /dev/null
2 +++ b/ext/libevent/CREDITS
3 @@ -0,0 +1 @@
4 +Antony Dovgal, Arnaud Le Blanc
5 --- /dev/null
6 +++ b/ext/libevent/config.m4
7 @@ -0,0 +1,52 @@
8 +dnl $Id: config.m4 287913 2009-08-31 08:45:42Z tony2001 $
9 +
10 +PHP_ARG_WITH(libevent, for libevent support,
11 +[ --with-libevent Include libevent support])
12 +
13 +if test "$PHP_LIBEVENT" != "no"; then
14 + SEARCH_PATH="/usr /usr/local"
15 + SEARCH_FOR="/include/event.h"
16 +
17 + if test "$PHP_LIBEVENT" = "yes"; then
18 + AC_MSG_CHECKING([for libevent headers in default path])
19 + for i in $SEARCH_PATH ; do
20 + if test -r $i/$SEARCH_FOR; then
21 + LIBEVENT_DIR=$i
22 + AC_MSG_RESULT(found in $i)
23 + fi
24 + done
25 + else
26 + AC_MSG_CHECKING([for libevent headers in $PHP_LIBEVENT])
27 + if test -r $PHP_LIBEVENT/$SEARCH_FOR; then
28 + LIBEVENT_DIR=$PHP_LIBEVENT
29 + AC_MSG_RESULT([found])
30 + fi
31 + fi
32 +
33 + if test -z "$LIBEVENT_DIR"; then
34 + AC_MSG_RESULT([not found])
35 + AC_MSG_ERROR([Cannot find libevent headers])
36 + fi
37 +
38 + PHP_ADD_INCLUDE($LIBEVENT_DIR/include)
39 +
40 + LIBNAME=event
41 + LIBSYMBOL=event_base_new
42 +
43 + if test "x$PHP_LIBDIR" = "x"; then
44 + PHP_LIBDIR=lib
45 + fi
46 +
47 + PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
48 + [
49 + PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $LIBEVENT_DIR/$PHP_LIBDIR, LIBEVENT_SHARED_LIBADD)
50 + ],[
51 + AC_MSG_ERROR([wrong libevent version {1.4.+ is required} or lib not found])
52 + ],[
53 + -L$LIBEVENT_DIR/$PHP_LIBDIR
54 + ])
55 +
56 + PHP_ADD_EXTENSION_DEP(libevent, sockets, true)
57 + PHP_SUBST(LIBEVENT_SHARED_LIBADD)
58 + PHP_NEW_EXTENSION(libevent, libevent.c, $ext_shared)
59 +fi
60 --- /dev/null
61 +++ b/ext/libevent/libevent.c
62 @@ -0,0 +1,1564 @@
63 +/*
64 + +----------------------------------------------------------------------+
65 + | PHP Version 5 |
66 + +----------------------------------------------------------------------+
67 + | Copyright (c) 1997-2008 The PHP Group |
68 + +----------------------------------------------------------------------+
69 + | This source file is subject to version 3.01 of the PHP license, |
70 + | that is bundled with this package in the file LICENSE, and is |
71 + | available through the world-wide-web at the following url: |
72 + | http://www.php.net/license/3_01.txt |
73 + | If you did not receive a copy of the PHP license and are unable to |
74 + | obtain it through the world-wide-web, please send a note to |
75 + | license@php.net so we can mail you a copy immediately. |
76 + +----------------------------------------------------------------------+
77 + | Author: Antony Dovgal <tony@daylessday.org> |
78 + | Arnaud Le Blanc <lbarnaud@php.net> |
79 + +----------------------------------------------------------------------+
80 +*/
81 +
82 +/* $Id: libevent.c 300303 2010-06-09 10:43:38Z tony2001 $ */
83 +
84 +#ifdef HAVE_CONFIG_H
85 +#include "config.h"
86 +#endif
87 +
88 +#include "php.h"
89 +#include "php_ini.h"
90 +#include "ext/standard/info.h"
91 +#include "php_streams.h"
92 +#include "php_network.h"
93 +#include "php_libevent.h"
94 +
95 +#include <signal.h>
96 +
97 +#if PHP_VERSION_ID >= 50301 && (HAVE_SOCKETS || defined(COMPILE_DL_SOCKETS))
98 +# include "ext/sockets/php_sockets.h"
99 +# define LIBEVENT_SOCKETS_SUPPORT
100 +#endif
101 +
102 +#include <event.h>
103 +
104 +#if PHP_MAJOR_VERSION < 5
105 +# ifdef PHP_WIN32
106 +typedef SOCKET php_socket_t;
107 +# else
108 +typedef int php_socket_t;
109 +# endif
110 +
111 +# ifdef ZTS
112 +# define TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx
113 +# define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_ls
114 +# else
115 +# define TSRMLS_FETCH_FROM_CTX(ctx)
116 +# define TSRMLS_SET_CTX(ctx)
117 +# endif
118 +
119 +# ifndef Z_ADDREF_P
120 +# define Z_ADDREF_P(x) (x)->refcount++
121 +# endif
122 +#endif
123 +
124 +static int le_event_base;
125 +static int le_event;
126 +static int le_bufferevent;
127 +
128 +#ifdef COMPILE_DL_LIBEVENT
129 +ZEND_GET_MODULE(libevent)
130 +#endif
131 +
132 +typedef struct _php_event_base_t { /* {{{ */
133 + struct event_base *base;
134 + int rsrc_id;
135 + zend_uint events;
136 +} php_event_base_t;
137 +/* }}} */
138 +
139 +typedef struct _php_event_callback_t { /* {{{ */
140 + zval *func;
141 + zval *arg;
142 +} php_event_callback_t;
143 +/* }}} */
144 +
145 +typedef struct _php_event_t { /* {{{ */
146 + struct event *event;
147 + int rsrc_id;
148 + int stream_id;
149 + php_event_base_t *base;
150 + php_event_callback_t *callback;
151 +#ifdef ZTS
152 + void ***thread_ctx;
153 +#endif
154 + int in_free;
155 +} php_event_t;
156 +/* }}} */
157 +
158 +typedef struct _php_bufferevent_t { /* {{{ */
159 + struct bufferevent *bevent;
160 + int rsrc_id;
161 + php_event_base_t *base;
162 + zval *readcb;
163 + zval *writecb;
164 + zval *errorcb;
165 + zval *arg;
166 +#ifdef ZTS
167 + void ***thread_ctx;
168 +#endif
169 +} php_bufferevent_t;
170 +/* }}} */
171 +
172 +#define ZVAL_TO_BASE(zval, base) \
173 + ZEND_FETCH_RESOURCE(base, php_event_base_t *, &zval, -1, "event base", le_event_base)
174 +
175 +#define ZVAL_TO_EVENT(zval, event) \
176 + ZEND_FETCH_RESOURCE(event, php_event_t *, &zval, -1, "event", le_event)
177 +
178 +#define ZVAL_TO_BEVENT(zval, bevent) \
179 + ZEND_FETCH_RESOURCE(bevent, php_bufferevent_t *, &zval, -1, "buffer event", le_bufferevent)
180 +
181 +/* {{{ internal funcs */
182 +
183 +static inline void _php_event_callback_free(php_event_callback_t *callback) /* {{{ */
184 +{
185 + if (!callback) {
186 + return;
187 + }
188 +
189 + zval_ptr_dtor(&callback->func);
190 + if (callback->arg) {
191 + zval_ptr_dtor(&callback->arg);
192 + }
193 + efree(callback);
194 +}
195 +/* }}} */
196 +
197 +static void _php_event_base_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
198 +{
199 + php_event_base_t *base = (php_event_base_t*)rsrc->ptr;
200 +
201 + event_base_free(base->base);
202 + efree(base);
203 +}
204 +/* }}} */
205 +
206 +static void _php_event_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
207 +{
208 + php_event_t *event = (php_event_t*)rsrc->ptr;
209 + int base_id = -1;
210 +
211 + if (event->in_free) {
212 + return;
213 + }
214 +
215 + event->in_free = 1;
216 +
217 + if (event->base) {
218 + base_id = event->base->rsrc_id;
219 + --event->base->events;
220 + }
221 + if (event->stream_id >= 0) {
222 + zend_list_delete(event->stream_id);
223 + }
224 + event_del(event->event);
225 +
226 + _php_event_callback_free(event->callback);
227 + efree(event->event);
228 + efree(event);
229 +
230 + if (base_id >= 0) {
231 + zend_list_delete(base_id);
232 + }
233 +}
234 +/* }}} */
235 +
236 +static void _php_bufferevent_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
237 +{
238 + php_bufferevent_t *bevent = (php_bufferevent_t*)rsrc->ptr;
239 + int base_id = -1;
240 +
241 + if (bevent->base) {
242 + base_id = bevent->base->rsrc_id;
243 + --bevent->base->events;
244 + }
245 + if (bevent->readcb) {
246 + zval_ptr_dtor(&(bevent->readcb));
247 + }
248 + if (bevent->writecb) {
249 + zval_ptr_dtor(&(bevent->writecb));
250 + }
251 + if (bevent->errorcb) {
252 + zval_ptr_dtor(&(bevent->errorcb));
253 + }
254 + if (bevent->arg) {
255 + zval_ptr_dtor(&(bevent->arg));
256 + }
257 +
258 + bufferevent_free(bevent->bevent);
259 + efree(bevent);
260 +
261 + if (base_id >= 0) {
262 + zend_list_delete(base_id);
263 + }
264 +}
265 +/* }}} */
266 +
267 +static void _php_event_callback(int fd, short events, void *arg) /* {{{ */
268 +{
269 + zval *args[3];
270 + php_event_t *event = (php_event_t *)arg;
271 + php_event_callback_t *callback;
272 + zval retval;
273 + TSRMLS_FETCH_FROM_CTX(event ? event->thread_ctx : NULL);
274 +
275 + if (!event || !event->callback || !event->base) {
276 + return;
277 + }
278 +
279 + callback = event->callback;
280 +
281 + MAKE_STD_ZVAL(args[0]);
282 + if (event->stream_id >= 0) {
283 + ZVAL_RESOURCE(args[0], event->stream_id);
284 + zend_list_addref(event->stream_id);
285 + } else {
286 + ZVAL_NULL(args[0]);
287 + }
288 +
289 + MAKE_STD_ZVAL(args[1]);
290 + ZVAL_LONG(args[1], events);
291 +
292 + args[2] = callback->arg;
293 + Z_ADDREF_P(callback->arg);
294 +
295 + if (call_user_function(EG(function_table), NULL, callback->func, &retval, 3, args TSRMLS_CC) == SUCCESS) {
296 + zval_dtor(&retval);
297 + }
298 +
299 + zval_ptr_dtor(&(args[0]));
300 + zval_ptr_dtor(&(args[1]));
301 + zval_ptr_dtor(&(args[2]));
302 +
303 +}
304 +/* }}} */
305 +
306 +static void _php_bufferevent_readcb(struct bufferevent *be, void *arg) /* {{{ */
307 +{
308 + zval *args[2];
309 + zval retval;
310 + php_bufferevent_t *bevent = (php_bufferevent_t *)arg;
311 + TSRMLS_FETCH_FROM_CTX(bevent ? bevent->thread_ctx : NULL);
312 +
313 + if (!bevent || !bevent->base || !bevent->readcb) {
314 + return;
315 + }
316 +
317 + MAKE_STD_ZVAL(args[0]);
318 + ZVAL_RESOURCE(args[0], bevent->rsrc_id);
319 + zend_list_addref(bevent->rsrc_id); /* we do refcount-- later in zval_ptr_dtor */
320 +
321 + args[1] = bevent->arg;
322 + Z_ADDREF_P(args[1]);
323 +
324 + if (call_user_function(EG(function_table), NULL, bevent->readcb, &retval, 2, args TSRMLS_CC) == SUCCESS) {
325 + zval_dtor(&retval);
326 + }
327 +
328 + zval_ptr_dtor(&(args[0]));
329 + zval_ptr_dtor(&(args[1]));
330 +
331 +}
332 +/* }}} */
333 +
334 +static void _php_bufferevent_writecb(struct bufferevent *be, void *arg) /* {{{ */
335 +{
336 + zval *args[2];
337 + zval retval;
338 + php_bufferevent_t *bevent = (php_bufferevent_t *)arg;
339 + TSRMLS_FETCH_FROM_CTX(bevent ? bevent->thread_ctx : NULL);
340 +
341 + if (!bevent || !bevent->base || !bevent->writecb) {
342 + return;
343 + }
344 +
345 + MAKE_STD_ZVAL(args[0]);
346 + ZVAL_RESOURCE(args[0], bevent->rsrc_id);
347 + zend_list_addref(bevent->rsrc_id); /* we do refcount-- later in zval_ptr_dtor */
348 +
349 + args[1] = bevent->arg;
350 + Z_ADDREF_P(args[1]);
351 +
352 + if (call_user_function(EG(function_table), NULL, bevent->writecb, &retval, 2, args TSRMLS_CC) == SUCCESS) {
353 + zval_dtor(&retval);
354 + }
355 +
356 + zval_ptr_dtor(&(args[0]));
357 + zval_ptr_dtor(&(args[1]));
358 +
359 +}
360 +/* }}} */
361 +
362 +static void _php_bufferevent_errorcb(struct bufferevent *be, short what, void *arg) /* {{{ */
363 +{
364 + zval *args[3];
365 + zval retval;
366 + php_bufferevent_t *bevent = (php_bufferevent_t *)arg;
367 + TSRMLS_FETCH_FROM_CTX(bevent ? bevent->thread_ctx : NULL);
368 +
369 + if (!bevent || !bevent->base || !bevent->errorcb) {
370 + return;
371 + }
372 +
373 + MAKE_STD_ZVAL(args[0]);
374 + ZVAL_RESOURCE(args[0], bevent->rsrc_id);
375 + zend_list_addref(bevent->rsrc_id); /* we do refcount-- later in zval_ptr_dtor */
376 +
377 + MAKE_STD_ZVAL(args[1]);
378 + ZVAL_LONG(args[1], what);
379 +
380 + args[2] = bevent->arg;
381 + Z_ADDREF_P(args[2]);
382 +
383 + if (call_user_function(EG(function_table), NULL, bevent->errorcb, &retval, 3, args TSRMLS_CC) == SUCCESS) {
384 + zval_dtor(&retval);
385 + }
386 +
387 + zval_ptr_dtor(&(args[0]));
388 + zval_ptr_dtor(&(args[1]));
389 + zval_ptr_dtor(&(args[2]));
390 +
391 +}
392 +/* }}} */
393 +
394 +/* }}} */
395 +
396 +
397 +/* {{{ proto resource event_base_new()
398 + */
399 +static PHP_FUNCTION(event_base_new)
400 +{
401 + php_event_base_t *base;
402 +
403 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") != SUCCESS) {
404 + return;
405 + }
406 +
407 + base = emalloc(sizeof(php_event_base_t));
408 + base->base = event_base_new();
409 + if (!base->base) {
410 + efree(base);
411 + RETURN_FALSE;
412 + }
413 +
414 + base->events = 0;
415 +
416 + base->rsrc_id = zend_list_insert(base, le_event_base);
417 + RETURN_RESOURCE(base->rsrc_id);
418 +}
419 +/* }}} */
420 +
421 +/* {{{ proto void event_base_free(resource base)
422 + */
423 +static PHP_FUNCTION(event_base_free)
424 +{
425 + zval *zbase;
426 + php_event_base_t *base;
427 +
428 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zbase) != SUCCESS) {
429 + return;
430 + }
431 +
432 + ZVAL_TO_BASE(zbase, base);
433 +
434 + if (base->events > 0) {
435 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "base has events attached to it and cannot be freed");
436 + RETURN_FALSE;
437 + }
438 +
439 + zend_list_delete(base->rsrc_id);
440 +}
441 +/* }}} */
442 +
443 +/* {{{ proto int event_base_loop(resource base[, int flags])
444 + */
445 +static PHP_FUNCTION(event_base_loop)
446 +{
447 + zval *zbase;
448 + php_event_base_t *base;
449 + long flags = 0;
450 + int ret;
451 +
452 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zbase, &flags) != SUCCESS) {
453 + return;
454 + }
455 +
456 + ZVAL_TO_BASE(zbase, base);
457 + zend_list_addref(base->rsrc_id); /* make sure the base cannot be destroyed during the loop */
458 + ret = event_base_loop(base->base, flags);
459 + zend_list_delete(base->rsrc_id);
460 +
461 + RETURN_LONG(ret);
462 +}
463 +/* }}} */
464 +
465 +/* {{{ proto bool event_base_loopbreak(resource base)
466 + */
467 +static PHP_FUNCTION(event_base_loopbreak)
468 +{
469 + zval *zbase;
470 + php_event_base_t *base;
471 + int ret;
472 +
473 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zbase) != SUCCESS) {
474 + return;
475 + }
476 +
477 + ZVAL_TO_BASE(zbase, base);
478 + ret = event_base_loopbreak(base->base);
479 + if (ret == 0) {
480 + RETURN_TRUE;
481 + }
482 + RETURN_FALSE;
483 +}
484 +/* }}} */
485 +
486 +/* {{{ proto bool event_base_loopexit(resource base[, int timeout])
487 + */
488 +static PHP_FUNCTION(event_base_loopexit)
489 +{
490 + zval *zbase;
491 + php_event_base_t *base;
492 + int ret;
493 + long timeout = -1;
494 +
495 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zbase, &timeout) != SUCCESS) {
496 + return;
497 + }
498 +
499 + ZVAL_TO_BASE(zbase, base);
500 +
501 + if (timeout < 0) {
502 + ret = event_base_loopexit(base->base, NULL);
503 + } else {
504 + struct timeval time;
505 +
506 + time.tv_usec = timeout % 1000000;
507 + time.tv_sec = timeout / 1000000;
508 + ret = event_base_loopexit(base->base, &time);
509 + }
510 +
511 + if (ret == 0) {
512 + RETURN_TRUE;
513 + }
514 + RETURN_FALSE;
515 +}
516 +/* }}} */
517 +
518 +/* {{{ proto bool event_base_set(resource event, resource base)
519 + */
520 +static PHP_FUNCTION(event_base_set)
521 +{
522 + zval *zbase, *zevent;
523 + php_event_base_t *base, *old_base;
524 + php_event_t *event;
525 + int ret;
526 +
527 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &zevent, &zbase) != SUCCESS) {
528 + return;
529 + }
530 +
531 + ZVAL_TO_BASE(zbase, base);
532 + ZVAL_TO_EVENT(zevent, event);
533 +
534 + old_base = event->base;
535 + ret = event_base_set(base->base, event->event);
536 +
537 + if (ret == 0) {
538 + if (base != old_base) {
539 + /* make sure the base is destroyed after the event */
540 + zend_list_addref(base->rsrc_id);
541 + ++base->events;
542 + }
543 +
544 + if (old_base) {
545 + --old_base->events;
546 + zend_list_delete(old_base->rsrc_id);
547 + }
548 +
549 + event->base = base;
550 + RETURN_TRUE;
551 + }
552 + RETURN_FALSE;
553 +}
554 +/* }}} */
555 +
556 +/* {{{ proto bool event_base_priority_init(resource base, int npriorities)
557 + */
558 +static PHP_FUNCTION(event_base_priority_init)
559 +{
560 + zval *zbase;
561 + php_event_base_t *base;
562 + long npriorities;
563 + int ret;
564 +
565 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zbase, &npriorities) != SUCCESS) {
566 + return;
567 + }
568 +
569 + ZVAL_TO_BASE(zbase, base);
570 +
571 + if (npriorities < 0) {
572 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "npriorities cannot be less than zero");
573 + RETURN_FALSE;
574 + }
575 +
576 + ret = event_base_priority_init(base->base, npriorities);
577 + if (ret == 0) {
578 + RETURN_TRUE;
579 + }
580 + RETURN_FALSE;
581 +}
582 +/* }}} */
583 +
584 +
585 +/* {{{ proto resource event_new()
586 + */
587 +static PHP_FUNCTION(event_new)
588 +{
589 + php_event_t *event;
590 +
591 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") != SUCCESS) {
592 + return;
593 + }
594 +
595 + event = emalloc(sizeof(php_event_t));
596 + event->event = ecalloc(1, sizeof(struct event));
597 +
598 + event->stream_id = -1;
599 + event->callback = NULL;
600 + event->base = NULL;
601 + event->in_free = 0;
602 + TSRMLS_SET_CTX(event->thread_ctx);
603 +
604 + event->rsrc_id = zend_list_insert(event, le_event);
605 + RETURN_RESOURCE(event->rsrc_id);
606 +}
607 +/* }}} */
608 +
609 +/* {{{ proto void event_free(resource event)
610 + */
611 +static PHP_FUNCTION(event_free)
612 +{
613 + zval *zevent;
614 + php_event_t *event;
615 +
616 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zevent) != SUCCESS) {
617 + return;
618 + }
619 +
620 + ZVAL_TO_EVENT(zevent, event);
621 + zend_list_delete(event->rsrc_id);
622 +}
623 +/* }}} */
624 +
625 +/* {{{ proto bool event_add(resource event[, int timeout])
626 + */
627 +static PHP_FUNCTION(event_add)
628 +{
629 + zval *zevent;
630 + php_event_t *event;
631 + int ret;
632 + long timeout = -1;
633 +
634 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zevent, &timeout) != SUCCESS) {
635 + return;
636 + }
637 +
638 + ZVAL_TO_EVENT(zevent, event);
639 +
640 + if (!event->base) {
641 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add event without an event base");
642 + RETURN_FALSE;
643 + }
644 +
645 + if (timeout < 0) {
646 + ret = event_add(event->event, NULL);
647 + } else {
648 + struct timeval time;
649 +
650 + time.tv_usec = timeout % 1000000;
651 + time.tv_sec = timeout / 1000000;
652 + ret = event_add(event->event, &time);
653 + }
654 +
655 + if (ret != 0) {
656 + RETURN_FALSE;
657 + }
658 +
659 + RETURN_TRUE;
660 +}
661 +/* }}} */
662 +
663 +/* {{{ proto bool event_set(resource event, resource fd, int events, mixed callback[, mixed arg])
664 + */
665 +static PHP_FUNCTION(event_set)
666 +{
667 + zval *zevent, **fd, *zcallback, *zarg = NULL;
668 + php_event_t *event;
669 + long events;
670 + php_event_callback_t *callback, *old_callback;
671 + char *func_name;
672 + php_stream *stream;
673 + php_socket_t file_desc;
674 +#ifdef LIBEVENT_SOCKETS_SUPPORT
675 + php_socket *php_sock;
676 +#endif
677 +
678 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZlz|z", &zevent, &fd, &events, &zcallback, &zarg) != SUCCESS) {
679 + return;
680 + }
681 +
682 + ZVAL_TO_EVENT(zevent, event);
683 +
684 + if (events & EV_SIGNAL) {
685 + /* signal support */
686 + convert_to_long_ex(fd);
687 + file_desc = Z_LVAL_PP(fd);
688 + if (file_desc < 0 || file_desc >= NSIG) {
689 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid signal passed");
690 + RETURN_FALSE;
691 + }
692 + } else {
693 + if (ZEND_FETCH_RESOURCE_NO_RETURN(stream, php_stream *, fd, -1, NULL, php_file_le_stream())) {
694 + if (php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&file_desc, 1) != SUCCESS || file_desc < 0) {
695 + RETURN_FALSE;
696 + }
697 + } else {
698 +#ifdef LIBEVENT_SOCKETS_SUPPORT
699 + if (ZEND_FETCH_RESOURCE_NO_RETURN(php_sock, php_socket *, fd, -1, NULL, php_sockets_le_socket())) {
700 + file_desc = php_sock->bsd_socket;
701 + } else {
702 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "fd argument must be either valid PHP stream or valid PHP socket resource");
703 + RETURN_FALSE;
704 + }
705 +#else
706 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "fd argument must be valid PHP stream resource");
707 + RETURN_FALSE;
708 +#endif
709 + }
710 + }
711 +
712 + if (!zend_is_callable(zcallback, 0, &func_name TSRMLS_CC)) {
713 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid callback", func_name);
714 + efree(func_name);
715 + RETURN_FALSE;
716 + }
717 + efree(func_name);
718 +
719 + zval_add_ref(&zcallback);
720 + if (zarg) {
721 + zval_add_ref(&zarg);
722 + } else {
723 + ALLOC_INIT_ZVAL(zarg);
724 + }
725 +
726 + callback = emalloc(sizeof(php_event_callback_t));
727 + callback->func = zcallback;
728 + callback->arg = zarg;
729 +
730 + old_callback = event->callback;
731 + event->callback = callback;
732 + if (events & EV_SIGNAL) {
733 + event->stream_id = -1;
734 + } else {
735 + zend_list_addref(Z_LVAL_PP(fd));
736 + event->stream_id = Z_LVAL_PP(fd);
737 + }
738 +
739 + event_set(event->event, (int)file_desc, (short)events, _php_event_callback, event);
740 +
741 + if (old_callback) {
742 + _php_event_callback_free(old_callback);
743 + }
744 + RETURN_TRUE;
745 +}
746 +/* }}} */
747 +
748 +/* {{{ proto bool event_del(resource event)
749 + */
750 +static PHP_FUNCTION(event_del)
751 +{
752 + zval *zevent;
753 + php_event_t *event;
754 +
755 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zevent) != SUCCESS) {
756 + return;
757 + }
758 +
759 + ZVAL_TO_EVENT(zevent, event);
760 +
761 + if (!event->base) {
762 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to delete event without an event base");
763 + RETURN_FALSE;
764 + }
765 +
766 + if (event_del(event->event) == 0) {
767 + RETURN_TRUE;
768 + }
769 + RETURN_FALSE;
770 +}
771 +/* }}} */
772 +
773 +
774 +/* {{{ proto bool event_timer_set(resource event, mixed callback[, mixed arg])
775 + */
776 +static PHP_FUNCTION(event_timer_set)
777 +{
778 + zval *zevent, *zcallback, *zarg = NULL;
779 + php_event_t *event;
780 + php_event_callback_t *callback, *old_callback;
781 + char *func_name;
782 +
783 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|z", &zevent, &zcallback, &zarg) != SUCCESS) {
784 + return;
785 + }
786 +
787 + ZVAL_TO_EVENT(zevent, event);
788 +
789 + if (!zend_is_callable(zcallback, 0, &func_name TSRMLS_CC)) {
790 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid callback", func_name);
791 + efree(func_name);
792 + RETURN_FALSE;
793 + }
794 + efree(func_name);
795 +
796 + zval_add_ref(&zcallback);
797 + if (zarg) {
798 + zval_add_ref(&zarg);
799 + } else {
800 + ALLOC_INIT_ZVAL(zarg);
801 + }
802 +
803 + callback = emalloc(sizeof(php_event_callback_t));
804 + callback->func = zcallback;
805 + callback->arg = zarg;
806 +
807 + old_callback = event->callback;
808 + event->callback = callback;
809 + if (event->stream_id >= 0) {
810 + zend_list_delete(event->stream_id);
811 + }
812 + event->stream_id = -1;
813 +
814 + event_set(event->event, -1, 0, _php_event_callback, event);
815 +
816 + if (old_callback) {
817 + _php_event_callback_free(old_callback);
818 + }
819 + RETURN_TRUE;
820 +}
821 +/* }}} */
822 +
823 +/* {{{ proto bool event_timer_pending(resource event[, int timeout])
824 + */
825 +static PHP_FUNCTION(event_timer_pending)
826 +{
827 + zval *zevent;
828 + php_event_t *event;
829 + int ret;
830 + long timeout = -1;
831 +
832 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zevent, &timeout) != SUCCESS) {
833 + return;
834 + }
835 +
836 + ZVAL_TO_EVENT(zevent, event);
837 +
838 + if (timeout < 0) {
839 + ret = event_pending(event->event, EV_TIMEOUT, NULL);
840 + } else {
841 + struct timeval time;
842 +
843 + time.tv_usec = timeout % 1000000;
844 + time.tv_sec = timeout / 1000000;
845 + ret = event_pending(event->event, EV_TIMEOUT, &time);
846 + }
847 +
848 + if (ret != 0) {
849 + RETURN_FALSE;
850 + }
851 + RETURN_TRUE;
852 +}
853 +/* }}} */
854 +
855 +
856 +
857 +/* {{{ proto resource event_buffer_new(resource stream, mixed readcb, mixed writecb, mixed errorcb[, mixed arg])
858 + */
859 +static PHP_FUNCTION(event_buffer_new)
860 +{
861 + php_bufferevent_t *bevent;
862 + php_stream *stream;
863 + zval *zstream, *zreadcb, *zwritecb, *zerrorcb, *zarg = NULL;
864 + php_socket_t fd;
865 + char *func_name;
866 +#ifdef LIBEVENT_SOCKETS_SUPPORT
867 + php_socket *php_sock;
868 +#endif
869 +
870 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzzz|z", &zstream, &zreadcb, &zwritecb, &zerrorcb, &zarg) != SUCCESS) {
871 + return;
872 + }
873 +
874 + if (ZEND_FETCH_RESOURCE_NO_RETURN(stream, php_stream *, &zstream, -1, NULL, php_file_le_stream())) {
875 + if (php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&fd, 1) != SUCCESS || fd < 0) {
876 + RETURN_FALSE;
877 + }
878 + } else {
879 +#ifdef LIBEVENT_SOCKETS_SUPPORT
880 + if (ZEND_FETCH_RESOURCE_NO_RETURN(php_sock, php_socket *, &zstream, -1, NULL, php_sockets_le_socket())) {
881 + fd = php_sock->bsd_socket;
882 + } else {
883 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream argument must be either valid PHP stream or valid PHP socket resource");
884 + RETURN_FALSE;
885 + }
886 +#else
887 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream argument must be valid PHP stream resource");
888 + RETURN_FALSE;
889 +#endif
890 + }
891 +
892 + if (Z_TYPE_P(zreadcb) != IS_NULL) {
893 + if (!zend_is_callable(zreadcb, 0, &func_name TSRMLS_CC)) {
894 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid read callback", func_name);
895 + efree(func_name);
896 + RETURN_FALSE;
897 + }
898 + efree(func_name);
899 + } else {
900 + zreadcb = NULL;
901 + }
902 +
903 + if (Z_TYPE_P(zwritecb) != IS_NULL) {
904 + if (!zend_is_callable(zwritecb, 0, &func_name TSRMLS_CC)) {
905 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid write callback", func_name);
906 + efree(func_name);
907 + RETURN_FALSE;
908 + }
909 + efree(func_name);
910 + } else {
911 + zwritecb = NULL;
912 + }
913 +
914 + if (!zend_is_callable(zerrorcb, 0, &func_name TSRMLS_CC)) {
915 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid error callback", func_name);
916 + efree(func_name);
917 + RETURN_FALSE;
918 + }
919 + efree(func_name);
920 +
921 + bevent = emalloc(sizeof(php_bufferevent_t));
922 + bevent->bevent = bufferevent_new(fd, _php_bufferevent_readcb, _php_bufferevent_writecb, _php_bufferevent_errorcb, bevent);
923 +
924 + bevent->base = NULL;
925 +
926 + if (zreadcb) {
927 + zval_add_ref(&zreadcb);
928 + }
929 + bevent->readcb = zreadcb;
930 +
931 + if (zwritecb) {
932 + zval_add_ref(&zwritecb);
933 + }
934 + bevent->writecb = zwritecb;
935 +
936 + zval_add_ref(&zerrorcb);
937 + bevent->errorcb = zerrorcb;
938 +
939 + if (zarg) {
940 + zval_add_ref(&zarg);
941 + bevent->arg = zarg;
942 + } else {
943 + ALLOC_INIT_ZVAL(bevent->arg);
944 + }
945 +
946 + TSRMLS_SET_CTX(bevent->thread_ctx);
947 +
948 + bevent->rsrc_id = zend_list_insert(bevent, le_bufferevent);
949 + RETURN_RESOURCE(bevent->rsrc_id);
950 +}
951 +/* }}} */
952 +
953 +/* {{{ proto void event_buffer_free(resource bevent)
954 + */
955 +static PHP_FUNCTION(event_buffer_free)
956 +{
957 + zval *zbevent;
958 + php_bufferevent_t *bevent;
959 +
960 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zbevent) != SUCCESS) {
961 + return;
962 + }
963 +
964 + ZVAL_TO_BEVENT(zbevent, bevent);
965 + zend_list_delete(bevent->rsrc_id);
966 +}
967 +/* }}} */
968 +
969 +/* {{{ proto bool event_buffer_base_set(resource bevent, resource base)
970 + */
971 +static PHP_FUNCTION(event_buffer_base_set)
972 +{
973 + zval *zbase, *zbevent;
974 + php_event_base_t *base, *old_base;
975 + php_bufferevent_t *bevent;
976 + int ret;
977 +
978 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &zbevent, &zbase) != SUCCESS) {
979 + return;
980 + }
981 +
982 + ZVAL_TO_BASE(zbase, base);
983 + ZVAL_TO_BEVENT(zbevent, bevent);
984 +
985 + old_base = bevent->base;
986 + ret = bufferevent_base_set(base->base, bevent->bevent);
987 +
988 + if (ret == 0) {
989 + if (base != old_base) {
990 + /* make sure the base is destroyed after the event */
991 + zend_list_addref(base->rsrc_id);
992 + ++base->events;
993 + }
994 +
995 + if (old_base) {
996 + --old_base->events;
997 + zend_list_delete(old_base->rsrc_id);
998 + }
999 +
1000 + bevent->base = base;
1001 + RETURN_TRUE;
1002 + }
1003 + RETURN_FALSE;
1004 +}
1005 +/* }}} */
1006 +
1007 +/* {{{ proto bool event_buffer_priority_set(resource bevent, int priority)
1008 + */
1009 +static PHP_FUNCTION(event_buffer_priority_set)
1010 +{
1011 + zval *zbevent;
1012 + php_bufferevent_t *bevent;
1013 + long priority;
1014 + int ret;
1015 +
1016 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zbevent, &priority) != SUCCESS) {
1017 + return;
1018 + }
1019 +
1020 + ZVAL_TO_BEVENT(zbevent, bevent);
1021 +
1022 + if (!bevent->base) {
1023 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set event priority without an event base");
1024 + RETURN_FALSE;
1025 + }
1026 +
1027 + ret = bufferevent_priority_set(bevent->bevent, priority);
1028 +
1029 + if (ret == 0) {
1030 + RETURN_TRUE;
1031 + }
1032 + RETURN_FALSE;
1033 +}
1034 +/* }}} */
1035 +
1036 +/* {{{ proto bool event_buffer_write(resource bevent, string data[, int data_size])
1037 + */
1038 +static PHP_FUNCTION(event_buffer_write)
1039 +{
1040 + zval *zbevent;
1041 + php_bufferevent_t *bevent;
1042 + char *data;
1043 + int data_len;
1044 + long data_size = -1;
1045 + int ret;
1046 +
1047 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &zbevent, &data, &data_len, &data_size) != SUCCESS) {
1048 + return;
1049 + }
1050 +
1051 + ZVAL_TO_BEVENT(zbevent, bevent);
1052 +
1053 + if (ZEND_NUM_ARGS() < 3 || data_size < 0) {
1054 + data_size = data_len;
1055 + } else if (data_size > data_len) {
1056 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_size out of range");
1057 + RETURN_FALSE;
1058 + }
1059 +
1060 + ret = bufferevent_write(bevent->bevent, (const void *)data, data_size);
1061 +
1062 + if (ret == 0) {
1063 + RETURN_TRUE;
1064 + }
1065 + RETURN_FALSE;
1066 +}
1067 +/* }}} */
1068 +
1069 +/* {{{ proto string event_buffer_read(resource bevent, int data_size)
1070 + */
1071 +static PHP_FUNCTION(event_buffer_read)
1072 +{
1073 + zval *zbevent;
1074 + php_bufferevent_t *bevent;
1075 + char *data;
1076 + long data_size;
1077 + int ret;
1078 +
1079 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zbevent, &data_size) != SUCCESS) {
1080 + return;
1081 + }
1082 +
1083 + ZVAL_TO_BEVENT(zbevent, bevent);
1084 +
1085 + if (data_size == 0) {
1086 + RETURN_EMPTY_STRING();
1087 + } else if (data_size < 0) {
1088 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_size cannot be less than zero");
1089 + RETURN_FALSE;
1090 + }
1091 +
1092 + data = safe_emalloc((int)data_size, sizeof(char), 1);
1093 +
1094 + ret = bufferevent_read(bevent->bevent, data, data_size);
1095 + if (ret > 0) {
1096 + if (ret > data_size) { /* paranoia */
1097 + ret = data_size;
1098 + }
1099 + data[ret] = '\0';
1100 + RETURN_STRINGL(data, ret, 0);
1101 + }
1102 + efree(data);
1103 + RETURN_EMPTY_STRING();
1104 +}
1105 +/* }}} */
1106 +
1107 +/* {{{ proto bool event_buffer_enable(resource bevent, int events)
1108 + */
1109 +static PHP_FUNCTION(event_buffer_enable)
1110 +{
1111 + zval *zbevent;
1112 + php_bufferevent_t *bevent;
1113 + long events;
1114 + int ret;
1115 +
1116 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zbevent, &events) != SUCCESS) {
1117 + return;
1118 + }
1119 +
1120 + ZVAL_TO_BEVENT(zbevent, bevent);
1121 +
1122 + ret = bufferevent_enable(bevent->bevent, events);
1123 +
1124 + if (ret == 0) {
1125 + RETURN_TRUE;
1126 + }
1127 + RETURN_FALSE;
1128 +}
1129 +/* }}} */
1130 +
1131 +/* {{{ proto bool event_buffer_disable(resource bevent, int events)
1132 + */
1133 +static PHP_FUNCTION(event_buffer_disable)
1134 +{
1135 + zval *zbevent;
1136 + php_bufferevent_t *bevent;
1137 + long events;
1138 + int ret;
1139 +
1140 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zbevent, &events) != SUCCESS) {
1141 + return;
1142 + }
1143 +
1144 + ZVAL_TO_BEVENT(zbevent, bevent);
1145 +
1146 + ret = bufferevent_disable(bevent->bevent, events);
1147 +
1148 + if (ret == 0) {
1149 + RETURN_TRUE;
1150 + }
1151 + RETURN_FALSE;
1152 +}
1153 +/* }}} */
1154 +
1155 +/* {{{ proto void event_buffer_timeout_set(resource bevent, int read_timeout, int write_timeout)
1156 + */
1157 +static PHP_FUNCTION(event_buffer_timeout_set)
1158 +{
1159 + zval *zbevent;
1160 + php_bufferevent_t *bevent;
1161 + long read_timeout, write_timeout;
1162 +
1163 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &zbevent, &read_timeout, &write_timeout) != SUCCESS) {
1164 + return;
1165 + }
1166 +
1167 + ZVAL_TO_BEVENT(zbevent, bevent);
1168 + bufferevent_settimeout(bevent->bevent, read_timeout, write_timeout);
1169 +}
1170 +/* }}} */
1171 +
1172 +/* {{{ proto void event_buffer_watermark_set(resource bevent, int events, int lowmark, int highmark)
1173 + */
1174 +static PHP_FUNCTION(event_buffer_watermark_set)
1175 +{
1176 + zval *zbevent;
1177 + php_bufferevent_t *bevent;
1178 + long events, lowmark, highmark;
1179 +
1180 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlll", &zbevent, &events, &lowmark, &highmark) != SUCCESS) {
1181 + return;
1182 + }
1183 +
1184 + ZVAL_TO_BEVENT(zbevent, bevent);
1185 + bufferevent_setwatermark(bevent->bevent, events, lowmark, highmark);
1186 +}
1187 +/* }}} */
1188 +
1189 +/* {{{ proto void event_buffer_fd_set(resource bevent, resource fd)
1190 + */
1191 +static PHP_FUNCTION(event_buffer_fd_set)
1192 +{
1193 + zval *zbevent, *zfd;
1194 + php_stream *stream;
1195 + php_bufferevent_t *bevent;
1196 + php_socket_t fd;
1197 +#ifdef LIBEVENT_SOCKETS_SUPPORT
1198 + php_socket *php_sock;
1199 +#endif
1200 +
1201 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &zbevent, &zfd) != SUCCESS) {
1202 + return;
1203 + }
1204 +
1205 + ZVAL_TO_BEVENT(zbevent, bevent);
1206 + if (ZEND_FETCH_RESOURCE_NO_RETURN(stream, php_stream *, &zfd, -1, NULL, php_file_le_stream())) {
1207 + if (php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&fd, 1) != SUCCESS || fd < 0) {
1208 + RETURN_FALSE;
1209 + }
1210 + } else {
1211 +#ifdef LIBEVENT_SOCKETS_SUPPORT
1212 + if (ZEND_FETCH_RESOURCE_NO_RETURN(php_sock, php_socket *, &zfd, -1, NULL, php_sockets_le_socket())) {
1213 + fd = php_sock->bsd_socket;
1214 + } else {
1215 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "fd argument must be either valid PHP stream or valid PHP socket resource");
1216 + RETURN_FALSE;
1217 + }
1218 +#else
1219 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "fd argument must be valid PHP stream resource");
1220 + RETURN_FALSE;
1221 +#endif
1222 + }
1223 +
1224 + bufferevent_setfd(bevent->bevent, fd);
1225 +}
1226 +/* }}} */
1227 +
1228 +/* {{{ proto resource event_buffer_set_callback(resource bevent, mixed readcb, mixed writecb, mixed errorcb[, mixed arg])
1229 + */
1230 +static PHP_FUNCTION(event_buffer_set_callback)
1231 +{
1232 + php_bufferevent_t *bevent;
1233 + zval *zbevent, *zreadcb, *zwritecb, *zerrorcb, *zarg = NULL;
1234 + char *func_name;
1235 +
1236 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzzz|z", &zbevent, &zreadcb, &zwritecb, &zerrorcb, &zarg) != SUCCESS) {
1237 + return;
1238 + }
1239 +
1240 + ZVAL_TO_BEVENT(zbevent, bevent);
1241 +
1242 + if (Z_TYPE_P(zreadcb) != IS_NULL) {
1243 + if (!zend_is_callable(zreadcb, 0, &func_name TSRMLS_CC)) {
1244 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid read callback", func_name);
1245 + efree(func_name);
1246 + RETURN_FALSE;
1247 + }
1248 + efree(func_name);
1249 + } else {
1250 + zreadcb = NULL;
1251 + }
1252 +
1253 + if (Z_TYPE_P(zwritecb) != IS_NULL) {
1254 + if (!zend_is_callable(zwritecb, 0, &func_name TSRMLS_CC)) {
1255 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid write callback", func_name);
1256 + efree(func_name);
1257 + RETURN_FALSE;
1258 + }
1259 + efree(func_name);
1260 + } else {
1261 + zwritecb = NULL;
1262 + }
1263 +
1264 + if (Z_TYPE_P(zerrorcb) != IS_NULL) {
1265 + if (!zend_is_callable(zerrorcb, 0, &func_name TSRMLS_CC)) {
1266 + php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid error callback", func_name);
1267 + efree(func_name);
1268 + RETURN_FALSE;
1269 + }
1270 + efree(func_name);
1271 + } else {
1272 + zerrorcb = NULL;
1273 + }
1274 +
1275 + if (zreadcb) {
1276 + zval_add_ref(&zreadcb);
1277 +
1278 + if (bevent->readcb) {
1279 + zval_ptr_dtor(&bevent->readcb);
1280 + }
1281 + bevent->readcb = zreadcb;
1282 + } else {
1283 + if (bevent->readcb) {
1284 + zval_ptr_dtor(&bevent->readcb);
1285 + }
1286 + bevent->readcb = NULL;
1287 + }
1288 +
1289 + if (zwritecb) {
1290 + zval_add_ref(&zwritecb);
1291 +
1292 + if (bevent->writecb) {
1293 + zval_ptr_dtor(&bevent->writecb);
1294 + }
1295 + bevent->writecb = zwritecb;
1296 + } else {
1297 + if (bevent->writecb) {
1298 + zval_ptr_dtor(&bevent->writecb);
1299 + }
1300 + bevent->writecb = NULL;
1301 + }
1302 +
1303 + if (zerrorcb) {
1304 + zval_add_ref(&zerrorcb);
1305 +
1306 + if (bevent->errorcb) {
1307 + zval_ptr_dtor(&bevent->errorcb);
1308 + }
1309 + bevent->errorcb = zerrorcb;
1310 + }
1311 +
1312 + if (zarg) {
1313 + zval_add_ref(&zarg);
1314 + if (bevent->arg) {
1315 + zval_ptr_dtor(&bevent->arg);
1316 + }
1317 + bevent->arg = zarg;
1318 + }
1319 +
1320 + RETURN_TRUE;
1321 +}
1322 +/* }}} */
1323 +
1324 +
1325 +/* {{{ PHP_MINIT_FUNCTION
1326 + */
1327 +static PHP_MINIT_FUNCTION(libevent)
1328 +{
1329 + le_event_base = zend_register_list_destructors_ex(_php_event_base_dtor, NULL, "event base", module_number);
1330 + le_event = zend_register_list_destructors_ex(_php_event_dtor, NULL, "event", module_number);
1331 + le_bufferevent = zend_register_list_destructors_ex(_php_bufferevent_dtor, NULL, "buffer event", module_number);
1332 +
1333 + REGISTER_LONG_CONSTANT("EV_TIMEOUT", EV_TIMEOUT, CONST_CS | CONST_PERSISTENT);
1334 + REGISTER_LONG_CONSTANT("EV_READ", EV_READ, CONST_CS | CONST_PERSISTENT);
1335 + REGISTER_LONG_CONSTANT("EV_WRITE", EV_WRITE, CONST_CS | CONST_PERSISTENT);
1336 + REGISTER_LONG_CONSTANT("EV_SIGNAL", EV_SIGNAL, CONST_CS | CONST_PERSISTENT);
1337 + REGISTER_LONG_CONSTANT("EV_PERSIST", EV_PERSIST, CONST_CS | CONST_PERSISTENT);
1338 + REGISTER_LONG_CONSTANT("EVLOOP_NONBLOCK", EVLOOP_NONBLOCK, CONST_CS | CONST_PERSISTENT);
1339 + REGISTER_LONG_CONSTANT("EVLOOP_ONCE", EVLOOP_ONCE, CONST_CS | CONST_PERSISTENT);
1340 +
1341 + REGISTER_LONG_CONSTANT("EVBUFFER_READ", EVBUFFER_READ, CONST_CS | CONST_PERSISTENT);
1342 + REGISTER_LONG_CONSTANT("EVBUFFER_WRITE", EVBUFFER_WRITE, CONST_CS | CONST_PERSISTENT);
1343 + REGISTER_LONG_CONSTANT("EVBUFFER_EOF", EVBUFFER_EOF, CONST_CS | CONST_PERSISTENT);
1344 + REGISTER_LONG_CONSTANT("EVBUFFER_ERROR", EVBUFFER_ERROR, CONST_CS | CONST_PERSISTENT);
1345 + REGISTER_LONG_CONSTANT("EVBUFFER_TIMEOUT", EVBUFFER_TIMEOUT, CONST_CS | CONST_PERSISTENT);
1346 +
1347 + return SUCCESS;
1348 +}
1349 +/* }}} */
1350 +
1351 +/* {{{ PHP_MINFO_FUNCTION
1352 + */
1353 +static PHP_MINFO_FUNCTION(libevent)
1354 +{
1355 + char buf[64];
1356 +
1357 +
1358 + php_info_print_table_start();
1359 + php_info_print_table_header(2, "libevent support", "enabled");
1360 + php_info_print_table_row(2, "extension version", PHP_LIBEVENT_VERSION);
1361 + php_info_print_table_row(2, "Revision", "$Revision: 300303 $");
1362 +
1363 + snprintf(buf, sizeof(buf) - 1, "%s", event_get_version());
1364 + php_info_print_table_row(2, "libevent version", buf);
1365 +
1366 + php_info_print_table_end();
1367 +}
1368 +/* }}} */
1369 +
1370 +#if PHP_MAJOR_VERSION >= 5
1371 +/* {{{ arginfo */
1372 +#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || PHP_MAJOR_VERSION > 5
1373 +# define EVENT_ARGINFO
1374 +#else
1375 +# define EVENT_ARGINFO static
1376 +#endif
1377 +
1378 +EVENT_ARGINFO
1379 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_base_loop, 0, 0, 1)
1380 + ZEND_ARG_INFO(0, base)
1381 + ZEND_ARG_INFO(0, flags)
1382 +ZEND_END_ARG_INFO()
1383 +
1384 +EVENT_ARGINFO
1385 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_base_loopbreak, 0, 0, 1)
1386 + ZEND_ARG_INFO(0, base)
1387 +ZEND_END_ARG_INFO()
1388 +
1389 +EVENT_ARGINFO
1390 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_base_loopexit, 0, 0, 1)
1391 + ZEND_ARG_INFO(0, base)
1392 + ZEND_ARG_INFO(0, timeout)
1393 +ZEND_END_ARG_INFO()
1394 +
1395 +EVENT_ARGINFO
1396 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_base_set, 0, 0, 2)
1397 + ZEND_ARG_INFO(0, event)
1398 + ZEND_ARG_INFO(0, base)
1399 +ZEND_END_ARG_INFO()
1400 +
1401 +EVENT_ARGINFO
1402 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_base_priority_init, 0, 0, 2)
1403 + ZEND_ARG_INFO(0, base)
1404 + ZEND_ARG_INFO(0, npriorities)
1405 +ZEND_END_ARG_INFO()
1406 +
1407 +EVENT_ARGINFO
1408 +ZEND_BEGIN_ARG_INFO(arginfo_event_new, 0)
1409 +ZEND_END_ARG_INFO()
1410 +
1411 +EVENT_ARGINFO
1412 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_add, 0, 0, 1)
1413 + ZEND_ARG_INFO(0, event)
1414 + ZEND_ARG_INFO(0, timeout)
1415 +ZEND_END_ARG_INFO()
1416 +
1417 +EVENT_ARGINFO
1418 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_set, 0, 0, 4)
1419 + ZEND_ARG_INFO(0, event)
1420 + ZEND_ARG_INFO(0, fd)
1421 + ZEND_ARG_INFO(0, events)
1422 + ZEND_ARG_INFO(0, callback)
1423 + ZEND_ARG_INFO(0, arg)
1424 +ZEND_END_ARG_INFO()
1425 +
1426 +EVENT_ARGINFO
1427 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_del, 0, 0, 1)
1428 + ZEND_ARG_INFO(0, event)
1429 +ZEND_END_ARG_INFO()
1430 +
1431 +EVENT_ARGINFO
1432 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_new, 0, 0, 4)
1433 + ZEND_ARG_INFO(0, stream)
1434 + ZEND_ARG_INFO(0, readcb)
1435 + ZEND_ARG_INFO(0, writecb)
1436 + ZEND_ARG_INFO(0, errorcb)
1437 + ZEND_ARG_INFO(0, arg)
1438 +ZEND_END_ARG_INFO()
1439 +
1440 +EVENT_ARGINFO
1441 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_free, 0, 0, 1)
1442 + ZEND_ARG_INFO(0, bevent)
1443 +ZEND_END_ARG_INFO()
1444 +
1445 +EVENT_ARGINFO
1446 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_base_set, 0, 0, 2)
1447 + ZEND_ARG_INFO(0, bevent)
1448 + ZEND_ARG_INFO(0, base)
1449 +ZEND_END_ARG_INFO()
1450 +
1451 +EVENT_ARGINFO
1452 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_priority_set, 0, 0, 2)
1453 + ZEND_ARG_INFO(0, bevent)
1454 + ZEND_ARG_INFO(0, priority)
1455 +ZEND_END_ARG_INFO()
1456 +
1457 +EVENT_ARGINFO
1458 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_write, 0, 0, 2)
1459 + ZEND_ARG_INFO(0, bevent)
1460 + ZEND_ARG_INFO(0, data)
1461 + ZEND_ARG_INFO(0, data_size)
1462 +ZEND_END_ARG_INFO()
1463 +
1464 +EVENT_ARGINFO
1465 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_read, 0, 0, 2)
1466 + ZEND_ARG_INFO(0, bevent)
1467 + ZEND_ARG_INFO(0, data_size)
1468 +ZEND_END_ARG_INFO()
1469 +
1470 +EVENT_ARGINFO
1471 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_disable, 0, 0, 2)
1472 + ZEND_ARG_INFO(0, bevent)
1473 + ZEND_ARG_INFO(0, events)
1474 +ZEND_END_ARG_INFO()
1475 +
1476 +EVENT_ARGINFO
1477 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_timeout_set, 0, 0, 3)
1478 + ZEND_ARG_INFO(0, bevent)
1479 + ZEND_ARG_INFO(0, read_timeout)
1480 + ZEND_ARG_INFO(0, write_timeout)
1481 +ZEND_END_ARG_INFO()
1482 +
1483 +EVENT_ARGINFO
1484 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_watermark_set, 0, 0, 4)
1485 + ZEND_ARG_INFO(0, bevent)
1486 + ZEND_ARG_INFO(0, events)
1487 + ZEND_ARG_INFO(0, lowmark)
1488 + ZEND_ARG_INFO(0, highmark)
1489 +ZEND_END_ARG_INFO()
1490 +
1491 +EVENT_ARGINFO
1492 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_fd_set, 0, 0, 2)
1493 + ZEND_ARG_INFO(0, bevent)
1494 + ZEND_ARG_INFO(0, fd)
1495 +ZEND_END_ARG_INFO()
1496 +
1497 +EVENT_ARGINFO
1498 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_set_callback, 0, 0, 4)
1499 + ZEND_ARG_INFO(0, bevent)
1500 + ZEND_ARG_INFO(0, readcb)
1501 + ZEND_ARG_INFO(0, writecb)
1502 + ZEND_ARG_INFO(0, errorcb)
1503 + ZEND_ARG_INFO(0, arg)
1504 +ZEND_END_ARG_INFO()
1505 +
1506 +EVENT_ARGINFO
1507 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_timer_set, 0, 0, 2)
1508 + ZEND_ARG_INFO(0, event)
1509 + ZEND_ARG_INFO(0, callback)
1510 + ZEND_ARG_INFO(0, arg)
1511 +ZEND_END_ARG_INFO()
1512 +
1513 +EVENT_ARGINFO
1514 +ZEND_BEGIN_ARG_INFO_EX(arginfo_event_timer_pending, 0, 0, 1)
1515 + ZEND_ARG_INFO(0, event)
1516 + ZEND_ARG_INFO(0, timeout)
1517 +ZEND_END_ARG_INFO()
1518 +/* }}} */
1519 +
1520 +/* {{{ libevent_functions[]
1521 + */
1522 +#if ZEND_MODULE_API_NO >= 20071006
1523 +const
1524 +#endif
1525 +zend_function_entry libevent_functions[] = {
1526 + PHP_FE(event_base_new, arginfo_event_new)
1527 + PHP_FE(event_base_free, arginfo_event_base_loopbreak)
1528 + PHP_FE(event_base_loop, arginfo_event_base_loop)
1529 + PHP_FE(event_base_loopbreak, arginfo_event_base_loopbreak)
1530 + PHP_FE(event_base_loopexit, arginfo_event_base_loopexit)
1531 + PHP_FE(event_base_set, arginfo_event_base_set)
1532 + PHP_FE(event_base_priority_init, arginfo_event_base_priority_init)
1533 + PHP_FE(event_new, arginfo_event_new)
1534 + PHP_FE(event_free, arginfo_event_del)
1535 + PHP_FE(event_add, arginfo_event_add)
1536 + PHP_FE(event_set, arginfo_event_set)
1537 + PHP_FE(event_del, arginfo_event_del)
1538 + PHP_FE(event_buffer_new, arginfo_event_buffer_new)
1539 + PHP_FE(event_buffer_free, arginfo_event_buffer_free)
1540 + PHP_FE(event_buffer_base_set, arginfo_event_buffer_base_set)
1541 + PHP_FE(event_buffer_priority_set, arginfo_event_buffer_priority_set)
1542 + PHP_FE(event_buffer_write, arginfo_event_buffer_write)
1543 + PHP_FE(event_buffer_read, arginfo_event_buffer_read)
1544 + PHP_FE(event_buffer_enable, arginfo_event_buffer_disable)
1545 + PHP_FE(event_buffer_disable, arginfo_event_buffer_disable)
1546 + PHP_FE(event_buffer_timeout_set, arginfo_event_buffer_timeout_set)
1547 + PHP_FE(event_buffer_watermark_set, arginfo_event_buffer_watermark_set)
1548 + PHP_FE(event_buffer_fd_set, arginfo_event_buffer_fd_set)
1549 + PHP_FE(event_buffer_set_callback, arginfo_event_buffer_set_callback)
1550 + PHP_FALIAS(event_timer_new, event_new, arginfo_event_new)
1551 + PHP_FE(event_timer_set, arginfo_event_timer_set)
1552 + PHP_FE(event_timer_pending, arginfo_event_timer_pending)
1553 + PHP_FALIAS(event_timer_add, event_add, arginfo_event_add)
1554 + PHP_FALIAS(event_timer_del, event_del, arginfo_event_del)
1555 + {NULL, NULL, NULL}
1556 +};
1557 +/* }}} */
1558 +#else
1559 +/* {{{ libevent_functions[]
1560 + */
1561 +zend_function_entry libevent_functions[] = {
1562 + PHP_FE(event_base_new, NULL)
1563 + PHP_FE(event_base_free, NULL)
1564 + PHP_FE(event_base_loop, NULL)
1565 + PHP_FE(event_base_loopbreak, NULL)
1566 + PHP_FE(event_base_loopexit, NULL)
1567 + PHP_FE(event_base_set, NULL)
1568 + PHP_FE(event_base_priority_init, NULL)
1569 + PHP_FE(event_new, NULL)
1570 + PHP_FE(event_free, NULL)
1571 + PHP_FE(event_add, NULL)
1572 + PHP_FE(event_set, NULL)
1573 + PHP_FE(event_del, NULL)
1574 + PHP_FE(event_buffer_new, NULL)
1575 + PHP_FE(event_buffer_free, NULL)
1576 + PHP_FE(event_buffer_base_set, NULL)
1577 + PHP_FE(event_buffer_priority_set, NULL)
1578 + PHP_FE(event_buffer_write, NULL)
1579 + PHP_FE(event_buffer_read, NULL)
1580 + PHP_FE(event_buffer_enable, NULL)
1581 + PHP_FE(event_buffer_disable, NULL)
1582 + PHP_FE(event_buffer_timeout_set, NULL)
1583 + PHP_FE(event_buffer_watermark_set, NULL)
1584 + PHP_FE(event_buffer_fd_set, NULL)
1585 + PHP_FALIAS(event_timer_new, event_new, NULL)
1586 + PHP_FE(event_timer_set, NULL)
1587 + PHP_FE(event_timer_pending, NULL)
1588 + PHP_FALIAS(event_timer_add, event_add, NULL)
1589 + PHP_FALIAS(event_timer_del, event_del, NULL)
1590 + {NULL, NULL, NULL}
1591 +};
1592 +/* }}} */
1593 +#endif
1594 +
1595 +static const zend_module_dep libevent_deps[] = { /* {{{ */
1596 + ZEND_MOD_OPTIONAL("sockets")
1597 + {NULL, NULL, NULL}
1598 +};
1599 +/* }}} */
1600 +
1601 +/* {{{ libevent_module_entry
1602 + */
1603 +zend_module_entry libevent_module_entry = {
1604 + STANDARD_MODULE_HEADER_EX,
1605 + NULL,
1606 + libevent_deps,
1607 + "libevent",
1608 + libevent_functions,
1609 + PHP_MINIT(libevent),
1610 + NULL,
1611 + NULL,
1612 + NULL,
1613 + PHP_MINFO(libevent),
1614 + PHP_LIBEVENT_VERSION,
1615 + STANDARD_MODULE_PROPERTIES
1616 +};
1617 +/* }}} */
1618 +
1619 +/*
1620 + * Local variables:
1621 + * tab-width: 4
1622 + * c-basic-offset: 4
1623 + * End:
1624 + * vim600: noet sw=4 ts=4 fdm=marker
1625 + * vim<600: noet sw=4 ts=4
1626 + */
1627 --- /dev/null
1628 +++ b/ext/libevent/libevent.php
1629 @@ -0,0 +1,58 @@
1630 +<?php
1631 +
1632 +/* poll STDIN using basic API */
1633 +
1634 +function foo($fd, $events, $arg)
1635 +{
1636 + static $i;
1637 +
1638 + $i++;
1639 +
1640 + if ($i == 10) {
1641 + event_base_loopexit($arg[1]);
1642 + }
1643 + var_dump(fread($fd, 1000));
1644 +}
1645 +
1646 +
1647 +$base = event_base_new();
1648 +$event = event_new();
1649 +
1650 +$fd = STDIN;
1651 +
1652 +var_dump(event_set($event, $fd, EV_READ | EV_PERSIST, "foo", array($event, $base)));
1653 +var_dump(event_set($event, $fd, EV_READ | EV_PERSIST, "foo", array($event, $base)));
1654 +
1655 +event_base_set($event, $base);
1656 +
1657 +var_dump(event_add($event));
1658 +var_dump(event_base_loop($base));
1659 +
1660 +exit;
1661 +
1662 +/* poll STDIN using event_buffer API */
1663 +
1664 +function foo2($buf, $arg)
1665 +{
1666 + static $i;
1667 +
1668 + $i++;
1669 +
1670 + if ($i == 10) {
1671 + event_base_loopexit($arg);
1672 + }
1673 + var_dump($buf);
1674 + var_dump(event_buffer_read($buf, 10));
1675 +}
1676 +
1677 +$base = event_base_new();
1678 +$b = event_buffer_new(STDIN, "foo2", NULL, "foo2", $base);
1679 +
1680 +event_buffer_base_set($b, $base);
1681 +event_buffer_enable($b, EV_READ);
1682 +
1683 +event_base_loop($base);
1684 +
1685 +
1686 +
1687 +?>
1688 --- /dev/null
1689 +++ b/ext/libevent/php_libevent.h
1690 @@ -0,0 +1,68 @@
1691 +/*
1692 + +----------------------------------------------------------------------+
1693 + | PHP Version 5 |
1694 + +----------------------------------------------------------------------+
1695 + | Copyright (c) 1997-2008 The PHP Group |
1696 + +----------------------------------------------------------------------+
1697 + | This source file is subject to version 3.01 of the PHP license, |
1698 + | that is bundled with this package in the file LICENSE, and is |
1699 + | available through the world-wide-web at the following url: |
1700 + | http://www.php.net/license/3_01.txt |
1701 + | If you did not receive a copy of the PHP license and are unable to |
1702 + | obtain it through the world-wide-web, please send a note to |
1703 + | license@php.net so we can mail you a copy immediately. |
1704 + +----------------------------------------------------------------------+
1705 + | Author: Antony Dovgal <tony@daylessday.org> |
1706 + | Arnaud Le Blanc <lbarnaud@php.net> |
1707 + +----------------------------------------------------------------------+
1708 +*/
1709 +
1710 +/* $Id: php_libevent.h 300687 2010-06-23 08:13:24Z tony2001 $ */
1711 +
1712 +#ifndef PHP_LIBEVENT_H
1713 +#define PHP_LIBEVENT_H
1714 +
1715 +#define PHP_LIBEVENT_VERSION "0.0.4"
1716 +
1717 +extern zend_module_entry libevent_module_entry;
1718 +#define phpext_libevent_ptr &libevent_module_entry
1719 +
1720 +#ifdef ZTS
1721 +#include "TSRM.h"
1722 +#endif
1723 +
1724 +#ifndef zend_always_inline
1725 +# if defined(__GNUC__)
1726 +# define zend_always_inline inline __attribute__((always_inline))
1727 +# elif defined(_MSC_VER)
1728 +# define zend_always_inline __forceinline
1729 +# else
1730 +# define zend_always_inline inline
1731 +# endif
1732 +#endif
1733 +
1734 +#ifndef Z_ADDREF_P
1735 +#define Z_ADDREF_P(pz) zval_addref_p(pz)
1736 +static zend_always_inline zend_uint zval_addref_p(zval* pz) {
1737 + return ++pz->refcount;
1738 +}
1739 +#endif
1740 +
1741 +#ifndef Z_DELREF_P
1742 +#define Z_DELREF_P(pz) zval_delref_p(pz)
1743 +static zend_always_inline zend_uint zval_delref_p(zval* pz) {
1744 + return --pz->refcount;
1745 +}
1746 +#endif
1747 +
1748 +#endif /* PHP_LIBEVENT_H */
1749 +
1750 +
1751 +/*
1752 + * Local variables:
1753 + * tab-width: 4
1754 + * c-basic-offset: 4
1755 + * End:
1756 + * vim600: noet sw=4 ts=4 fdm=marker
1757 + * vim<600: noet sw=4 ts=4
1758 + */