packages/lang/php5/patches/020-PECL-add-libevent.patch
mhei 495b7fe03c [packages] php5: PECL: include support for libevent
git-svn-id: svn://svn.openwrt.org/openwrt/packages@27838 3c298f89-4303-0410-b956-a3cf2f4a3e73
2011-07-30 06:38:53 +00:00

1759 lines
44 KiB
Diff

--- /dev/null
+++ b/ext/libevent/CREDITS
@@ -0,0 +1 @@
+Antony Dovgal, Arnaud Le Blanc
--- /dev/null
+++ b/ext/libevent/config.m4
@@ -0,0 +1,52 @@
+dnl $Id: config.m4 287913 2009-08-31 08:45:42Z tony2001 $
+
+PHP_ARG_WITH(libevent, for libevent support,
+[ --with-libevent Include libevent support])
+
+if test "$PHP_LIBEVENT" != "no"; then
+ SEARCH_PATH="/usr /usr/local"
+ SEARCH_FOR="/include/event.h"
+
+ if test "$PHP_LIBEVENT" = "yes"; then
+ AC_MSG_CHECKING([for libevent headers in default path])
+ for i in $SEARCH_PATH ; do
+ if test -r $i/$SEARCH_FOR; then
+ LIBEVENT_DIR=$i
+ AC_MSG_RESULT(found in $i)
+ fi
+ done
+ else
+ AC_MSG_CHECKING([for libevent headers in $PHP_LIBEVENT])
+ if test -r $PHP_LIBEVENT/$SEARCH_FOR; then
+ LIBEVENT_DIR=$PHP_LIBEVENT
+ AC_MSG_RESULT([found])
+ fi
+ fi
+
+ if test -z "$LIBEVENT_DIR"; then
+ AC_MSG_RESULT([not found])
+ AC_MSG_ERROR([Cannot find libevent headers])
+ fi
+
+ PHP_ADD_INCLUDE($LIBEVENT_DIR/include)
+
+ LIBNAME=event
+ LIBSYMBOL=event_base_new
+
+ if test "x$PHP_LIBDIR" = "x"; then
+ PHP_LIBDIR=lib
+ fi
+
+ PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
+ [
+ PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $LIBEVENT_DIR/$PHP_LIBDIR, LIBEVENT_SHARED_LIBADD)
+ ],[
+ AC_MSG_ERROR([wrong libevent version {1.4.+ is required} or lib not found])
+ ],[
+ -L$LIBEVENT_DIR/$PHP_LIBDIR
+ ])
+
+ PHP_ADD_EXTENSION_DEP(libevent, sockets, true)
+ PHP_SUBST(LIBEVENT_SHARED_LIBADD)
+ PHP_NEW_EXTENSION(libevent, libevent.c, $ext_shared)
+fi
--- /dev/null
+++ b/ext/libevent/libevent.c
@@ -0,0 +1,1564 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2008 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Antony Dovgal <tony@daylessday.org> |
+ | Arnaud Le Blanc <lbarnaud@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id: libevent.c 300303 2010-06-09 10:43:38Z tony2001 $ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "php_streams.h"
+#include "php_network.h"
+#include "php_libevent.h"
+
+#include <signal.h>
+
+#if PHP_VERSION_ID >= 50301 && (HAVE_SOCKETS || defined(COMPILE_DL_SOCKETS))
+# include "ext/sockets/php_sockets.h"
+# define LIBEVENT_SOCKETS_SUPPORT
+#endif
+
+#include <event.h>
+
+#if PHP_MAJOR_VERSION < 5
+# ifdef PHP_WIN32
+typedef SOCKET php_socket_t;
+# else
+typedef int php_socket_t;
+# endif
+
+# ifdef ZTS
+# define TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx
+# define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_ls
+# else
+# define TSRMLS_FETCH_FROM_CTX(ctx)
+# define TSRMLS_SET_CTX(ctx)
+# endif
+
+# ifndef Z_ADDREF_P
+# define Z_ADDREF_P(x) (x)->refcount++
+# endif
+#endif
+
+static int le_event_base;
+static int le_event;
+static int le_bufferevent;
+
+#ifdef COMPILE_DL_LIBEVENT
+ZEND_GET_MODULE(libevent)
+#endif
+
+typedef struct _php_event_base_t { /* {{{ */
+ struct event_base *base;
+ int rsrc_id;
+ zend_uint events;
+} php_event_base_t;
+/* }}} */
+
+typedef struct _php_event_callback_t { /* {{{ */
+ zval *func;
+ zval *arg;
+} php_event_callback_t;
+/* }}} */
+
+typedef struct _php_event_t { /* {{{ */
+ struct event *event;
+ int rsrc_id;
+ int stream_id;
+ php_event_base_t *base;
+ php_event_callback_t *callback;
+#ifdef ZTS
+ void ***thread_ctx;
+#endif
+ int in_free;
+} php_event_t;
+/* }}} */
+
+typedef struct _php_bufferevent_t { /* {{{ */
+ struct bufferevent *bevent;
+ int rsrc_id;
+ php_event_base_t *base;
+ zval *readcb;
+ zval *writecb;
+ zval *errorcb;
+ zval *arg;
+#ifdef ZTS
+ void ***thread_ctx;
+#endif
+} php_bufferevent_t;
+/* }}} */
+
+#define ZVAL_TO_BASE(zval, base) \
+ ZEND_FETCH_RESOURCE(base, php_event_base_t *, &zval, -1, "event base", le_event_base)
+
+#define ZVAL_TO_EVENT(zval, event) \
+ ZEND_FETCH_RESOURCE(event, php_event_t *, &zval, -1, "event", le_event)
+
+#define ZVAL_TO_BEVENT(zval, bevent) \
+ ZEND_FETCH_RESOURCE(bevent, php_bufferevent_t *, &zval, -1, "buffer event", le_bufferevent)
+
+/* {{{ internal funcs */
+
+static inline void _php_event_callback_free(php_event_callback_t *callback) /* {{{ */
+{
+ if (!callback) {
+ return;
+ }
+
+ zval_ptr_dtor(&callback->func);
+ if (callback->arg) {
+ zval_ptr_dtor(&callback->arg);
+ }
+ efree(callback);
+}
+/* }}} */
+
+static void _php_event_base_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
+{
+ php_event_base_t *base = (php_event_base_t*)rsrc->ptr;
+
+ event_base_free(base->base);
+ efree(base);
+}
+/* }}} */
+
+static void _php_event_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
+{
+ php_event_t *event = (php_event_t*)rsrc->ptr;
+ int base_id = -1;
+
+ if (event->in_free) {
+ return;
+ }
+
+ event->in_free = 1;
+
+ if (event->base) {
+ base_id = event->base->rsrc_id;
+ --event->base->events;
+ }
+ if (event->stream_id >= 0) {
+ zend_list_delete(event->stream_id);
+ }
+ event_del(event->event);
+
+ _php_event_callback_free(event->callback);
+ efree(event->event);
+ efree(event);
+
+ if (base_id >= 0) {
+ zend_list_delete(base_id);
+ }
+}
+/* }}} */
+
+static void _php_bufferevent_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
+{
+ php_bufferevent_t *bevent = (php_bufferevent_t*)rsrc->ptr;
+ int base_id = -1;
+
+ if (bevent->base) {
+ base_id = bevent->base->rsrc_id;
+ --bevent->base->events;
+ }
+ if (bevent->readcb) {
+ zval_ptr_dtor(&(bevent->readcb));
+ }
+ if (bevent->writecb) {
+ zval_ptr_dtor(&(bevent->writecb));
+ }
+ if (bevent->errorcb) {
+ zval_ptr_dtor(&(bevent->errorcb));
+ }
+ if (bevent->arg) {
+ zval_ptr_dtor(&(bevent->arg));
+ }
+
+ bufferevent_free(bevent->bevent);
+ efree(bevent);
+
+ if (base_id >= 0) {
+ zend_list_delete(base_id);
+ }
+}
+/* }}} */
+
+static void _php_event_callback(int fd, short events, void *arg) /* {{{ */
+{
+ zval *args[3];
+ php_event_t *event = (php_event_t *)arg;
+ php_event_callback_t *callback;
+ zval retval;
+ TSRMLS_FETCH_FROM_CTX(event ? event->thread_ctx : NULL);
+
+ if (!event || !event->callback || !event->base) {
+ return;
+ }
+
+ callback = event->callback;
+
+ MAKE_STD_ZVAL(args[0]);
+ if (event->stream_id >= 0) {
+ ZVAL_RESOURCE(args[0], event->stream_id);
+ zend_list_addref(event->stream_id);
+ } else {
+ ZVAL_NULL(args[0]);
+ }
+
+ MAKE_STD_ZVAL(args[1]);
+ ZVAL_LONG(args[1], events);
+
+ args[2] = callback->arg;
+ Z_ADDREF_P(callback->arg);
+
+ if (call_user_function(EG(function_table), NULL, callback->func, &retval, 3, args TSRMLS_CC) == SUCCESS) {
+ zval_dtor(&retval);
+ }
+
+ zval_ptr_dtor(&(args[0]));
+ zval_ptr_dtor(&(args[1]));
+ zval_ptr_dtor(&(args[2]));
+
+}
+/* }}} */
+
+static void _php_bufferevent_readcb(struct bufferevent *be, void *arg) /* {{{ */
+{
+ zval *args[2];
+ zval retval;
+ php_bufferevent_t *bevent = (php_bufferevent_t *)arg;
+ TSRMLS_FETCH_FROM_CTX(bevent ? bevent->thread_ctx : NULL);
+
+ if (!bevent || !bevent->base || !bevent->readcb) {
+ return;
+ }
+
+ MAKE_STD_ZVAL(args[0]);
+ ZVAL_RESOURCE(args[0], bevent->rsrc_id);
+ zend_list_addref(bevent->rsrc_id); /* we do refcount-- later in zval_ptr_dtor */
+
+ args[1] = bevent->arg;
+ Z_ADDREF_P(args[1]);
+
+ if (call_user_function(EG(function_table), NULL, bevent->readcb, &retval, 2, args TSRMLS_CC) == SUCCESS) {
+ zval_dtor(&retval);
+ }
+
+ zval_ptr_dtor(&(args[0]));
+ zval_ptr_dtor(&(args[1]));
+
+}
+/* }}} */
+
+static void _php_bufferevent_writecb(struct bufferevent *be, void *arg) /* {{{ */
+{
+ zval *args[2];
+ zval retval;
+ php_bufferevent_t *bevent = (php_bufferevent_t *)arg;
+ TSRMLS_FETCH_FROM_CTX(bevent ? bevent->thread_ctx : NULL);
+
+ if (!bevent || !bevent->base || !bevent->writecb) {
+ return;
+ }
+
+ MAKE_STD_ZVAL(args[0]);
+ ZVAL_RESOURCE(args[0], bevent->rsrc_id);
+ zend_list_addref(bevent->rsrc_id); /* we do refcount-- later in zval_ptr_dtor */
+
+ args[1] = bevent->arg;
+ Z_ADDREF_P(args[1]);
+
+ if (call_user_function(EG(function_table), NULL, bevent->writecb, &retval, 2, args TSRMLS_CC) == SUCCESS) {
+ zval_dtor(&retval);
+ }
+
+ zval_ptr_dtor(&(args[0]));
+ zval_ptr_dtor(&(args[1]));
+
+}
+/* }}} */
+
+static void _php_bufferevent_errorcb(struct bufferevent *be, short what, void *arg) /* {{{ */
+{
+ zval *args[3];
+ zval retval;
+ php_bufferevent_t *bevent = (php_bufferevent_t *)arg;
+ TSRMLS_FETCH_FROM_CTX(bevent ? bevent->thread_ctx : NULL);
+
+ if (!bevent || !bevent->base || !bevent->errorcb) {
+ return;
+ }
+
+ MAKE_STD_ZVAL(args[0]);
+ ZVAL_RESOURCE(args[0], bevent->rsrc_id);
+ zend_list_addref(bevent->rsrc_id); /* we do refcount-- later in zval_ptr_dtor */
+
+ MAKE_STD_ZVAL(args[1]);
+ ZVAL_LONG(args[1], what);
+
+ args[2] = bevent->arg;
+ Z_ADDREF_P(args[2]);
+
+ if (call_user_function(EG(function_table), NULL, bevent->errorcb, &retval, 3, args TSRMLS_CC) == SUCCESS) {
+ zval_dtor(&retval);
+ }
+
+ zval_ptr_dtor(&(args[0]));
+ zval_ptr_dtor(&(args[1]));
+ zval_ptr_dtor(&(args[2]));
+
+}
+/* }}} */
+
+/* }}} */
+
+
+/* {{{ proto resource event_base_new()
+ */
+static PHP_FUNCTION(event_base_new)
+{
+ php_event_base_t *base;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") != SUCCESS) {
+ return;
+ }
+
+ base = emalloc(sizeof(php_event_base_t));
+ base->base = event_base_new();
+ if (!base->base) {
+ efree(base);
+ RETURN_FALSE;
+ }
+
+ base->events = 0;
+
+ base->rsrc_id = zend_list_insert(base, le_event_base);
+ RETURN_RESOURCE(base->rsrc_id);
+}
+/* }}} */
+
+/* {{{ proto void event_base_free(resource base)
+ */
+static PHP_FUNCTION(event_base_free)
+{
+ zval *zbase;
+ php_event_base_t *base;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zbase) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BASE(zbase, base);
+
+ if (base->events > 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "base has events attached to it and cannot be freed");
+ RETURN_FALSE;
+ }
+
+ zend_list_delete(base->rsrc_id);
+}
+/* }}} */
+
+/* {{{ proto int event_base_loop(resource base[, int flags])
+ */
+static PHP_FUNCTION(event_base_loop)
+{
+ zval *zbase;
+ php_event_base_t *base;
+ long flags = 0;
+ int ret;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zbase, &flags) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BASE(zbase, base);
+ zend_list_addref(base->rsrc_id); /* make sure the base cannot be destroyed during the loop */
+ ret = event_base_loop(base->base, flags);
+ zend_list_delete(base->rsrc_id);
+
+ RETURN_LONG(ret);
+}
+/* }}} */
+
+/* {{{ proto bool event_base_loopbreak(resource base)
+ */
+static PHP_FUNCTION(event_base_loopbreak)
+{
+ zval *zbase;
+ php_event_base_t *base;
+ int ret;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zbase) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BASE(zbase, base);
+ ret = event_base_loopbreak(base->base);
+ if (ret == 0) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool event_base_loopexit(resource base[, int timeout])
+ */
+static PHP_FUNCTION(event_base_loopexit)
+{
+ zval *zbase;
+ php_event_base_t *base;
+ int ret;
+ long timeout = -1;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zbase, &timeout) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BASE(zbase, base);
+
+ if (timeout < 0) {
+ ret = event_base_loopexit(base->base, NULL);
+ } else {
+ struct timeval time;
+
+ time.tv_usec = timeout % 1000000;
+ time.tv_sec = timeout / 1000000;
+ ret = event_base_loopexit(base->base, &time);
+ }
+
+ if (ret == 0) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool event_base_set(resource event, resource base)
+ */
+static PHP_FUNCTION(event_base_set)
+{
+ zval *zbase, *zevent;
+ php_event_base_t *base, *old_base;
+ php_event_t *event;
+ int ret;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &zevent, &zbase) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BASE(zbase, base);
+ ZVAL_TO_EVENT(zevent, event);
+
+ old_base = event->base;
+ ret = event_base_set(base->base, event->event);
+
+ if (ret == 0) {
+ if (base != old_base) {
+ /* make sure the base is destroyed after the event */
+ zend_list_addref(base->rsrc_id);
+ ++base->events;
+ }
+
+ if (old_base) {
+ --old_base->events;
+ zend_list_delete(old_base->rsrc_id);
+ }
+
+ event->base = base;
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool event_base_priority_init(resource base, int npriorities)
+ */
+static PHP_FUNCTION(event_base_priority_init)
+{
+ zval *zbase;
+ php_event_base_t *base;
+ long npriorities;
+ int ret;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zbase, &npriorities) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BASE(zbase, base);
+
+ if (npriorities < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "npriorities cannot be less than zero");
+ RETURN_FALSE;
+ }
+
+ ret = event_base_priority_init(base->base, npriorities);
+ if (ret == 0) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+
+/* {{{ proto resource event_new()
+ */
+static PHP_FUNCTION(event_new)
+{
+ php_event_t *event;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") != SUCCESS) {
+ return;
+ }
+
+ event = emalloc(sizeof(php_event_t));
+ event->event = ecalloc(1, sizeof(struct event));
+
+ event->stream_id = -1;
+ event->callback = NULL;
+ event->base = NULL;
+ event->in_free = 0;
+ TSRMLS_SET_CTX(event->thread_ctx);
+
+ event->rsrc_id = zend_list_insert(event, le_event);
+ RETURN_RESOURCE(event->rsrc_id);
+}
+/* }}} */
+
+/* {{{ proto void event_free(resource event)
+ */
+static PHP_FUNCTION(event_free)
+{
+ zval *zevent;
+ php_event_t *event;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zevent) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_EVENT(zevent, event);
+ zend_list_delete(event->rsrc_id);
+}
+/* }}} */
+
+/* {{{ proto bool event_add(resource event[, int timeout])
+ */
+static PHP_FUNCTION(event_add)
+{
+ zval *zevent;
+ php_event_t *event;
+ int ret;
+ long timeout = -1;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zevent, &timeout) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_EVENT(zevent, event);
+
+ if (!event->base) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add event without an event base");
+ RETURN_FALSE;
+ }
+
+ if (timeout < 0) {
+ ret = event_add(event->event, NULL);
+ } else {
+ struct timeval time;
+
+ time.tv_usec = timeout % 1000000;
+ time.tv_sec = timeout / 1000000;
+ ret = event_add(event->event, &time);
+ }
+
+ if (ret != 0) {
+ RETURN_FALSE;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool event_set(resource event, resource fd, int events, mixed callback[, mixed arg])
+ */
+static PHP_FUNCTION(event_set)
+{
+ zval *zevent, **fd, *zcallback, *zarg = NULL;
+ php_event_t *event;
+ long events;
+ php_event_callback_t *callback, *old_callback;
+ char *func_name;
+ php_stream *stream;
+ php_socket_t file_desc;
+#ifdef LIBEVENT_SOCKETS_SUPPORT
+ php_socket *php_sock;
+#endif
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZlz|z", &zevent, &fd, &events, &zcallback, &zarg) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_EVENT(zevent, event);
+
+ if (events & EV_SIGNAL) {
+ /* signal support */
+ convert_to_long_ex(fd);
+ file_desc = Z_LVAL_PP(fd);
+ if (file_desc < 0 || file_desc >= NSIG) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid signal passed");
+ RETURN_FALSE;
+ }
+ } else {
+ if (ZEND_FETCH_RESOURCE_NO_RETURN(stream, php_stream *, fd, -1, NULL, php_file_le_stream())) {
+ if (php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&file_desc, 1) != SUCCESS || file_desc < 0) {
+ RETURN_FALSE;
+ }
+ } else {
+#ifdef LIBEVENT_SOCKETS_SUPPORT
+ if (ZEND_FETCH_RESOURCE_NO_RETURN(php_sock, php_socket *, fd, -1, NULL, php_sockets_le_socket())) {
+ file_desc = php_sock->bsd_socket;
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "fd argument must be either valid PHP stream or valid PHP socket resource");
+ RETURN_FALSE;
+ }
+#else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "fd argument must be valid PHP stream resource");
+ RETURN_FALSE;
+#endif
+ }
+ }
+
+ if (!zend_is_callable(zcallback, 0, &func_name TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid callback", func_name);
+ efree(func_name);
+ RETURN_FALSE;
+ }
+ efree(func_name);
+
+ zval_add_ref(&zcallback);
+ if (zarg) {
+ zval_add_ref(&zarg);
+ } else {
+ ALLOC_INIT_ZVAL(zarg);
+ }
+
+ callback = emalloc(sizeof(php_event_callback_t));
+ callback->func = zcallback;
+ callback->arg = zarg;
+
+ old_callback = event->callback;
+ event->callback = callback;
+ if (events & EV_SIGNAL) {
+ event->stream_id = -1;
+ } else {
+ zend_list_addref(Z_LVAL_PP(fd));
+ event->stream_id = Z_LVAL_PP(fd);
+ }
+
+ event_set(event->event, (int)file_desc, (short)events, _php_event_callback, event);
+
+ if (old_callback) {
+ _php_event_callback_free(old_callback);
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool event_del(resource event)
+ */
+static PHP_FUNCTION(event_del)
+{
+ zval *zevent;
+ php_event_t *event;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zevent) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_EVENT(zevent, event);
+
+ if (!event->base) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to delete event without an event base");
+ RETURN_FALSE;
+ }
+
+ if (event_del(event->event) == 0) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+
+/* {{{ proto bool event_timer_set(resource event, mixed callback[, mixed arg])
+ */
+static PHP_FUNCTION(event_timer_set)
+{
+ zval *zevent, *zcallback, *zarg = NULL;
+ php_event_t *event;
+ php_event_callback_t *callback, *old_callback;
+ char *func_name;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|z", &zevent, &zcallback, &zarg) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_EVENT(zevent, event);
+
+ if (!zend_is_callable(zcallback, 0, &func_name TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid callback", func_name);
+ efree(func_name);
+ RETURN_FALSE;
+ }
+ efree(func_name);
+
+ zval_add_ref(&zcallback);
+ if (zarg) {
+ zval_add_ref(&zarg);
+ } else {
+ ALLOC_INIT_ZVAL(zarg);
+ }
+
+ callback = emalloc(sizeof(php_event_callback_t));
+ callback->func = zcallback;
+ callback->arg = zarg;
+
+ old_callback = event->callback;
+ event->callback = callback;
+ if (event->stream_id >= 0) {
+ zend_list_delete(event->stream_id);
+ }
+ event->stream_id = -1;
+
+ event_set(event->event, -1, 0, _php_event_callback, event);
+
+ if (old_callback) {
+ _php_event_callback_free(old_callback);
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool event_timer_pending(resource event[, int timeout])
+ */
+static PHP_FUNCTION(event_timer_pending)
+{
+ zval *zevent;
+ php_event_t *event;
+ int ret;
+ long timeout = -1;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zevent, &timeout) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_EVENT(zevent, event);
+
+ if (timeout < 0) {
+ ret = event_pending(event->event, EV_TIMEOUT, NULL);
+ } else {
+ struct timeval time;
+
+ time.tv_usec = timeout % 1000000;
+ time.tv_sec = timeout / 1000000;
+ ret = event_pending(event->event, EV_TIMEOUT, &time);
+ }
+
+ if (ret != 0) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+
+
+/* {{{ proto resource event_buffer_new(resource stream, mixed readcb, mixed writecb, mixed errorcb[, mixed arg])
+ */
+static PHP_FUNCTION(event_buffer_new)
+{
+ php_bufferevent_t *bevent;
+ php_stream *stream;
+ zval *zstream, *zreadcb, *zwritecb, *zerrorcb, *zarg = NULL;
+ php_socket_t fd;
+ char *func_name;
+#ifdef LIBEVENT_SOCKETS_SUPPORT
+ php_socket *php_sock;
+#endif
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzzz|z", &zstream, &zreadcb, &zwritecb, &zerrorcb, &zarg) != SUCCESS) {
+ return;
+ }
+
+ if (ZEND_FETCH_RESOURCE_NO_RETURN(stream, php_stream *, &zstream, -1, NULL, php_file_le_stream())) {
+ if (php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&fd, 1) != SUCCESS || fd < 0) {
+ RETURN_FALSE;
+ }
+ } else {
+#ifdef LIBEVENT_SOCKETS_SUPPORT
+ if (ZEND_FETCH_RESOURCE_NO_RETURN(php_sock, php_socket *, &zstream, -1, NULL, php_sockets_le_socket())) {
+ fd = php_sock->bsd_socket;
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream argument must be either valid PHP stream or valid PHP socket resource");
+ RETURN_FALSE;
+ }
+#else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream argument must be valid PHP stream resource");
+ RETURN_FALSE;
+#endif
+ }
+
+ if (Z_TYPE_P(zreadcb) != IS_NULL) {
+ if (!zend_is_callable(zreadcb, 0, &func_name TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid read callback", func_name);
+ efree(func_name);
+ RETURN_FALSE;
+ }
+ efree(func_name);
+ } else {
+ zreadcb = NULL;
+ }
+
+ if (Z_TYPE_P(zwritecb) != IS_NULL) {
+ if (!zend_is_callable(zwritecb, 0, &func_name TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid write callback", func_name);
+ efree(func_name);
+ RETURN_FALSE;
+ }
+ efree(func_name);
+ } else {
+ zwritecb = NULL;
+ }
+
+ if (!zend_is_callable(zerrorcb, 0, &func_name TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid error callback", func_name);
+ efree(func_name);
+ RETURN_FALSE;
+ }
+ efree(func_name);
+
+ bevent = emalloc(sizeof(php_bufferevent_t));
+ bevent->bevent = bufferevent_new(fd, _php_bufferevent_readcb, _php_bufferevent_writecb, _php_bufferevent_errorcb, bevent);
+
+ bevent->base = NULL;
+
+ if (zreadcb) {
+ zval_add_ref(&zreadcb);
+ }
+ bevent->readcb = zreadcb;
+
+ if (zwritecb) {
+ zval_add_ref(&zwritecb);
+ }
+ bevent->writecb = zwritecb;
+
+ zval_add_ref(&zerrorcb);
+ bevent->errorcb = zerrorcb;
+
+ if (zarg) {
+ zval_add_ref(&zarg);
+ bevent->arg = zarg;
+ } else {
+ ALLOC_INIT_ZVAL(bevent->arg);
+ }
+
+ TSRMLS_SET_CTX(bevent->thread_ctx);
+
+ bevent->rsrc_id = zend_list_insert(bevent, le_bufferevent);
+ RETURN_RESOURCE(bevent->rsrc_id);
+}
+/* }}} */
+
+/* {{{ proto void event_buffer_free(resource bevent)
+ */
+static PHP_FUNCTION(event_buffer_free)
+{
+ zval *zbevent;
+ php_bufferevent_t *bevent;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zbevent) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BEVENT(zbevent, bevent);
+ zend_list_delete(bevent->rsrc_id);
+}
+/* }}} */
+
+/* {{{ proto bool event_buffer_base_set(resource bevent, resource base)
+ */
+static PHP_FUNCTION(event_buffer_base_set)
+{
+ zval *zbase, *zbevent;
+ php_event_base_t *base, *old_base;
+ php_bufferevent_t *bevent;
+ int ret;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &zbevent, &zbase) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BASE(zbase, base);
+ ZVAL_TO_BEVENT(zbevent, bevent);
+
+ old_base = bevent->base;
+ ret = bufferevent_base_set(base->base, bevent->bevent);
+
+ if (ret == 0) {
+ if (base != old_base) {
+ /* make sure the base is destroyed after the event */
+ zend_list_addref(base->rsrc_id);
+ ++base->events;
+ }
+
+ if (old_base) {
+ --old_base->events;
+ zend_list_delete(old_base->rsrc_id);
+ }
+
+ bevent->base = base;
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool event_buffer_priority_set(resource bevent, int priority)
+ */
+static PHP_FUNCTION(event_buffer_priority_set)
+{
+ zval *zbevent;
+ php_bufferevent_t *bevent;
+ long priority;
+ int ret;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zbevent, &priority) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BEVENT(zbevent, bevent);
+
+ if (!bevent->base) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set event priority without an event base");
+ RETURN_FALSE;
+ }
+
+ ret = bufferevent_priority_set(bevent->bevent, priority);
+
+ if (ret == 0) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool event_buffer_write(resource bevent, string data[, int data_size])
+ */
+static PHP_FUNCTION(event_buffer_write)
+{
+ zval *zbevent;
+ php_bufferevent_t *bevent;
+ char *data;
+ int data_len;
+ long data_size = -1;
+ int ret;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &zbevent, &data, &data_len, &data_size) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BEVENT(zbevent, bevent);
+
+ if (ZEND_NUM_ARGS() < 3 || data_size < 0) {
+ data_size = data_len;
+ } else if (data_size > data_len) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_size out of range");
+ RETURN_FALSE;
+ }
+
+ ret = bufferevent_write(bevent->bevent, (const void *)data, data_size);
+
+ if (ret == 0) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string event_buffer_read(resource bevent, int data_size)
+ */
+static PHP_FUNCTION(event_buffer_read)
+{
+ zval *zbevent;
+ php_bufferevent_t *bevent;
+ char *data;
+ long data_size;
+ int ret;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zbevent, &data_size) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BEVENT(zbevent, bevent);
+
+ if (data_size == 0) {
+ RETURN_EMPTY_STRING();
+ } else if (data_size < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_size cannot be less than zero");
+ RETURN_FALSE;
+ }
+
+ data = safe_emalloc((int)data_size, sizeof(char), 1);
+
+ ret = bufferevent_read(bevent->bevent, data, data_size);
+ if (ret > 0) {
+ if (ret > data_size) { /* paranoia */
+ ret = data_size;
+ }
+ data[ret] = '\0';
+ RETURN_STRINGL(data, ret, 0);
+ }
+ efree(data);
+ RETURN_EMPTY_STRING();
+}
+/* }}} */
+
+/* {{{ proto bool event_buffer_enable(resource bevent, int events)
+ */
+static PHP_FUNCTION(event_buffer_enable)
+{
+ zval *zbevent;
+ php_bufferevent_t *bevent;
+ long events;
+ int ret;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zbevent, &events) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BEVENT(zbevent, bevent);
+
+ ret = bufferevent_enable(bevent->bevent, events);
+
+ if (ret == 0) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool event_buffer_disable(resource bevent, int events)
+ */
+static PHP_FUNCTION(event_buffer_disable)
+{
+ zval *zbevent;
+ php_bufferevent_t *bevent;
+ long events;
+ int ret;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zbevent, &events) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BEVENT(zbevent, bevent);
+
+ ret = bufferevent_disable(bevent->bevent, events);
+
+ if (ret == 0) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto void event_buffer_timeout_set(resource bevent, int read_timeout, int write_timeout)
+ */
+static PHP_FUNCTION(event_buffer_timeout_set)
+{
+ zval *zbevent;
+ php_bufferevent_t *bevent;
+ long read_timeout, write_timeout;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &zbevent, &read_timeout, &write_timeout) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BEVENT(zbevent, bevent);
+ bufferevent_settimeout(bevent->bevent, read_timeout, write_timeout);
+}
+/* }}} */
+
+/* {{{ proto void event_buffer_watermark_set(resource bevent, int events, int lowmark, int highmark)
+ */
+static PHP_FUNCTION(event_buffer_watermark_set)
+{
+ zval *zbevent;
+ php_bufferevent_t *bevent;
+ long events, lowmark, highmark;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlll", &zbevent, &events, &lowmark, &highmark) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BEVENT(zbevent, bevent);
+ bufferevent_setwatermark(bevent->bevent, events, lowmark, highmark);
+}
+/* }}} */
+
+/* {{{ proto void event_buffer_fd_set(resource bevent, resource fd)
+ */
+static PHP_FUNCTION(event_buffer_fd_set)
+{
+ zval *zbevent, *zfd;
+ php_stream *stream;
+ php_bufferevent_t *bevent;
+ php_socket_t fd;
+#ifdef LIBEVENT_SOCKETS_SUPPORT
+ php_socket *php_sock;
+#endif
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &zbevent, &zfd) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BEVENT(zbevent, bevent);
+ if (ZEND_FETCH_RESOURCE_NO_RETURN(stream, php_stream *, &zfd, -1, NULL, php_file_le_stream())) {
+ if (php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&fd, 1) != SUCCESS || fd < 0) {
+ RETURN_FALSE;
+ }
+ } else {
+#ifdef LIBEVENT_SOCKETS_SUPPORT
+ if (ZEND_FETCH_RESOURCE_NO_RETURN(php_sock, php_socket *, &zfd, -1, NULL, php_sockets_le_socket())) {
+ fd = php_sock->bsd_socket;
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "fd argument must be either valid PHP stream or valid PHP socket resource");
+ RETURN_FALSE;
+ }
+#else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "fd argument must be valid PHP stream resource");
+ RETURN_FALSE;
+#endif
+ }
+
+ bufferevent_setfd(bevent->bevent, fd);
+}
+/* }}} */
+
+/* {{{ proto resource event_buffer_set_callback(resource bevent, mixed readcb, mixed writecb, mixed errorcb[, mixed arg])
+ */
+static PHP_FUNCTION(event_buffer_set_callback)
+{
+ php_bufferevent_t *bevent;
+ zval *zbevent, *zreadcb, *zwritecb, *zerrorcb, *zarg = NULL;
+ char *func_name;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzzz|z", &zbevent, &zreadcb, &zwritecb, &zerrorcb, &zarg) != SUCCESS) {
+ return;
+ }
+
+ ZVAL_TO_BEVENT(zbevent, bevent);
+
+ if (Z_TYPE_P(zreadcb) != IS_NULL) {
+ if (!zend_is_callable(zreadcb, 0, &func_name TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid read callback", func_name);
+ efree(func_name);
+ RETURN_FALSE;
+ }
+ efree(func_name);
+ } else {
+ zreadcb = NULL;
+ }
+
+ if (Z_TYPE_P(zwritecb) != IS_NULL) {
+ if (!zend_is_callable(zwritecb, 0, &func_name TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid write callback", func_name);
+ efree(func_name);
+ RETURN_FALSE;
+ }
+ efree(func_name);
+ } else {
+ zwritecb = NULL;
+ }
+
+ if (Z_TYPE_P(zerrorcb) != IS_NULL) {
+ if (!zend_is_callable(zerrorcb, 0, &func_name TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' is not a valid error callback", func_name);
+ efree(func_name);
+ RETURN_FALSE;
+ }
+ efree(func_name);
+ } else {
+ zerrorcb = NULL;
+ }
+
+ if (zreadcb) {
+ zval_add_ref(&zreadcb);
+
+ if (bevent->readcb) {
+ zval_ptr_dtor(&bevent->readcb);
+ }
+ bevent->readcb = zreadcb;
+ } else {
+ if (bevent->readcb) {
+ zval_ptr_dtor(&bevent->readcb);
+ }
+ bevent->readcb = NULL;
+ }
+
+ if (zwritecb) {
+ zval_add_ref(&zwritecb);
+
+ if (bevent->writecb) {
+ zval_ptr_dtor(&bevent->writecb);
+ }
+ bevent->writecb = zwritecb;
+ } else {
+ if (bevent->writecb) {
+ zval_ptr_dtor(&bevent->writecb);
+ }
+ bevent->writecb = NULL;
+ }
+
+ if (zerrorcb) {
+ zval_add_ref(&zerrorcb);
+
+ if (bevent->errorcb) {
+ zval_ptr_dtor(&bevent->errorcb);
+ }
+ bevent->errorcb = zerrorcb;
+ }
+
+ if (zarg) {
+ zval_add_ref(&zarg);
+ if (bevent->arg) {
+ zval_ptr_dtor(&bevent->arg);
+ }
+ bevent->arg = zarg;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+
+/* {{{ PHP_MINIT_FUNCTION
+ */
+static PHP_MINIT_FUNCTION(libevent)
+{
+ le_event_base = zend_register_list_destructors_ex(_php_event_base_dtor, NULL, "event base", module_number);
+ le_event = zend_register_list_destructors_ex(_php_event_dtor, NULL, "event", module_number);
+ le_bufferevent = zend_register_list_destructors_ex(_php_bufferevent_dtor, NULL, "buffer event", module_number);
+
+ REGISTER_LONG_CONSTANT("EV_TIMEOUT", EV_TIMEOUT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("EV_READ", EV_READ, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("EV_WRITE", EV_WRITE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("EV_SIGNAL", EV_SIGNAL, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("EV_PERSIST", EV_PERSIST, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("EVLOOP_NONBLOCK", EVLOOP_NONBLOCK, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("EVLOOP_ONCE", EVLOOP_ONCE, CONST_CS | CONST_PERSISTENT);
+
+ REGISTER_LONG_CONSTANT("EVBUFFER_READ", EVBUFFER_READ, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("EVBUFFER_WRITE", EVBUFFER_WRITE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("EVBUFFER_EOF", EVBUFFER_EOF, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("EVBUFFER_ERROR", EVBUFFER_ERROR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("EVBUFFER_TIMEOUT", EVBUFFER_TIMEOUT, CONST_CS | CONST_PERSISTENT);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_MINFO_FUNCTION
+ */
+static PHP_MINFO_FUNCTION(libevent)
+{
+ char buf[64];
+
+
+ php_info_print_table_start();
+ php_info_print_table_header(2, "libevent support", "enabled");
+ php_info_print_table_row(2, "extension version", PHP_LIBEVENT_VERSION);
+ php_info_print_table_row(2, "Revision", "$Revision: 300303 $");
+
+ snprintf(buf, sizeof(buf) - 1, "%s", event_get_version());
+ php_info_print_table_row(2, "libevent version", buf);
+
+ php_info_print_table_end();
+}
+/* }}} */
+
+#if PHP_MAJOR_VERSION >= 5
+/* {{{ arginfo */
+#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || PHP_MAJOR_VERSION > 5
+# define EVENT_ARGINFO
+#else
+# define EVENT_ARGINFO static
+#endif
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_base_loop, 0, 0, 1)
+ ZEND_ARG_INFO(0, base)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_base_loopbreak, 0, 0, 1)
+ ZEND_ARG_INFO(0, base)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_base_loopexit, 0, 0, 1)
+ ZEND_ARG_INFO(0, base)
+ ZEND_ARG_INFO(0, timeout)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_base_set, 0, 0, 2)
+ ZEND_ARG_INFO(0, event)
+ ZEND_ARG_INFO(0, base)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_base_priority_init, 0, 0, 2)
+ ZEND_ARG_INFO(0, base)
+ ZEND_ARG_INFO(0, npriorities)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO(arginfo_event_new, 0)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_add, 0, 0, 1)
+ ZEND_ARG_INFO(0, event)
+ ZEND_ARG_INFO(0, timeout)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_set, 0, 0, 4)
+ ZEND_ARG_INFO(0, event)
+ ZEND_ARG_INFO(0, fd)
+ ZEND_ARG_INFO(0, events)
+ ZEND_ARG_INFO(0, callback)
+ ZEND_ARG_INFO(0, arg)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_del, 0, 0, 1)
+ ZEND_ARG_INFO(0, event)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_new, 0, 0, 4)
+ ZEND_ARG_INFO(0, stream)
+ ZEND_ARG_INFO(0, readcb)
+ ZEND_ARG_INFO(0, writecb)
+ ZEND_ARG_INFO(0, errorcb)
+ ZEND_ARG_INFO(0, arg)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_free, 0, 0, 1)
+ ZEND_ARG_INFO(0, bevent)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_base_set, 0, 0, 2)
+ ZEND_ARG_INFO(0, bevent)
+ ZEND_ARG_INFO(0, base)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_priority_set, 0, 0, 2)
+ ZEND_ARG_INFO(0, bevent)
+ ZEND_ARG_INFO(0, priority)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_write, 0, 0, 2)
+ ZEND_ARG_INFO(0, bevent)
+ ZEND_ARG_INFO(0, data)
+ ZEND_ARG_INFO(0, data_size)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_read, 0, 0, 2)
+ ZEND_ARG_INFO(0, bevent)
+ ZEND_ARG_INFO(0, data_size)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_disable, 0, 0, 2)
+ ZEND_ARG_INFO(0, bevent)
+ ZEND_ARG_INFO(0, events)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_timeout_set, 0, 0, 3)
+ ZEND_ARG_INFO(0, bevent)
+ ZEND_ARG_INFO(0, read_timeout)
+ ZEND_ARG_INFO(0, write_timeout)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_watermark_set, 0, 0, 4)
+ ZEND_ARG_INFO(0, bevent)
+ ZEND_ARG_INFO(0, events)
+ ZEND_ARG_INFO(0, lowmark)
+ ZEND_ARG_INFO(0, highmark)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_fd_set, 0, 0, 2)
+ ZEND_ARG_INFO(0, bevent)
+ ZEND_ARG_INFO(0, fd)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_buffer_set_callback, 0, 0, 4)
+ ZEND_ARG_INFO(0, bevent)
+ ZEND_ARG_INFO(0, readcb)
+ ZEND_ARG_INFO(0, writecb)
+ ZEND_ARG_INFO(0, errorcb)
+ ZEND_ARG_INFO(0, arg)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_timer_set, 0, 0, 2)
+ ZEND_ARG_INFO(0, event)
+ ZEND_ARG_INFO(0, callback)
+ ZEND_ARG_INFO(0, arg)
+ZEND_END_ARG_INFO()
+
+EVENT_ARGINFO
+ZEND_BEGIN_ARG_INFO_EX(arginfo_event_timer_pending, 0, 0, 1)
+ ZEND_ARG_INFO(0, event)
+ ZEND_ARG_INFO(0, timeout)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/* {{{ libevent_functions[]
+ */
+#if ZEND_MODULE_API_NO >= 20071006
+const
+#endif
+zend_function_entry libevent_functions[] = {
+ PHP_FE(event_base_new, arginfo_event_new)
+ PHP_FE(event_base_free, arginfo_event_base_loopbreak)
+ PHP_FE(event_base_loop, arginfo_event_base_loop)
+ PHP_FE(event_base_loopbreak, arginfo_event_base_loopbreak)
+ PHP_FE(event_base_loopexit, arginfo_event_base_loopexit)
+ PHP_FE(event_base_set, arginfo_event_base_set)
+ PHP_FE(event_base_priority_init, arginfo_event_base_priority_init)
+ PHP_FE(event_new, arginfo_event_new)
+ PHP_FE(event_free, arginfo_event_del)
+ PHP_FE(event_add, arginfo_event_add)
+ PHP_FE(event_set, arginfo_event_set)
+ PHP_FE(event_del, arginfo_event_del)
+ PHP_FE(event_buffer_new, arginfo_event_buffer_new)
+ PHP_FE(event_buffer_free, arginfo_event_buffer_free)
+ PHP_FE(event_buffer_base_set, arginfo_event_buffer_base_set)
+ PHP_FE(event_buffer_priority_set, arginfo_event_buffer_priority_set)
+ PHP_FE(event_buffer_write, arginfo_event_buffer_write)
+ PHP_FE(event_buffer_read, arginfo_event_buffer_read)
+ PHP_FE(event_buffer_enable, arginfo_event_buffer_disable)
+ PHP_FE(event_buffer_disable, arginfo_event_buffer_disable)
+ PHP_FE(event_buffer_timeout_set, arginfo_event_buffer_timeout_set)
+ PHP_FE(event_buffer_watermark_set, arginfo_event_buffer_watermark_set)
+ PHP_FE(event_buffer_fd_set, arginfo_event_buffer_fd_set)
+ PHP_FE(event_buffer_set_callback, arginfo_event_buffer_set_callback)
+ PHP_FALIAS(event_timer_new, event_new, arginfo_event_new)
+ PHP_FE(event_timer_set, arginfo_event_timer_set)
+ PHP_FE(event_timer_pending, arginfo_event_timer_pending)
+ PHP_FALIAS(event_timer_add, event_add, arginfo_event_add)
+ PHP_FALIAS(event_timer_del, event_del, arginfo_event_del)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+#else
+/* {{{ libevent_functions[]
+ */
+zend_function_entry libevent_functions[] = {
+ PHP_FE(event_base_new, NULL)
+ PHP_FE(event_base_free, NULL)
+ PHP_FE(event_base_loop, NULL)
+ PHP_FE(event_base_loopbreak, NULL)
+ PHP_FE(event_base_loopexit, NULL)
+ PHP_FE(event_base_set, NULL)
+ PHP_FE(event_base_priority_init, NULL)
+ PHP_FE(event_new, NULL)
+ PHP_FE(event_free, NULL)
+ PHP_FE(event_add, NULL)
+ PHP_FE(event_set, NULL)
+ PHP_FE(event_del, NULL)
+ PHP_FE(event_buffer_new, NULL)
+ PHP_FE(event_buffer_free, NULL)
+ PHP_FE(event_buffer_base_set, NULL)
+ PHP_FE(event_buffer_priority_set, NULL)
+ PHP_FE(event_buffer_write, NULL)
+ PHP_FE(event_buffer_read, NULL)
+ PHP_FE(event_buffer_enable, NULL)
+ PHP_FE(event_buffer_disable, NULL)
+ PHP_FE(event_buffer_timeout_set, NULL)
+ PHP_FE(event_buffer_watermark_set, NULL)
+ PHP_FE(event_buffer_fd_set, NULL)
+ PHP_FALIAS(event_timer_new, event_new, NULL)
+ PHP_FE(event_timer_set, NULL)
+ PHP_FE(event_timer_pending, NULL)
+ PHP_FALIAS(event_timer_add, event_add, NULL)
+ PHP_FALIAS(event_timer_del, event_del, NULL)
+ {NULL, NULL, NULL}
+};
+/* }}} */
+#endif
+
+static const zend_module_dep libevent_deps[] = { /* {{{ */
+ ZEND_MOD_OPTIONAL("sockets")
+ {NULL, NULL, NULL}
+};
+/* }}} */
+
+/* {{{ libevent_module_entry
+ */
+zend_module_entry libevent_module_entry = {
+ STANDARD_MODULE_HEADER_EX,
+ NULL,
+ libevent_deps,
+ "libevent",
+ libevent_functions,
+ PHP_MINIT(libevent),
+ NULL,
+ NULL,
+ NULL,
+ PHP_MINFO(libevent),
+ PHP_LIBEVENT_VERSION,
+ STANDARD_MODULE_PROPERTIES
+};
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
--- /dev/null
+++ b/ext/libevent/libevent.php
@@ -0,0 +1,58 @@
+<?php
+
+/* poll STDIN using basic API */
+
+function foo($fd, $events, $arg)
+{
+ static $i;
+
+ $i++;
+
+ if ($i == 10) {
+ event_base_loopexit($arg[1]);
+ }
+ var_dump(fread($fd, 1000));
+}
+
+
+$base = event_base_new();
+$event = event_new();
+
+$fd = STDIN;
+
+var_dump(event_set($event, $fd, EV_READ | EV_PERSIST, "foo", array($event, $base)));
+var_dump(event_set($event, $fd, EV_READ | EV_PERSIST, "foo", array($event, $base)));
+
+event_base_set($event, $base);
+
+var_dump(event_add($event));
+var_dump(event_base_loop($base));
+
+exit;
+
+/* poll STDIN using event_buffer API */
+
+function foo2($buf, $arg)
+{
+ static $i;
+
+ $i++;
+
+ if ($i == 10) {
+ event_base_loopexit($arg);
+ }
+ var_dump($buf);
+ var_dump(event_buffer_read($buf, 10));
+}
+
+$base = event_base_new();
+$b = event_buffer_new(STDIN, "foo2", NULL, "foo2", $base);
+
+event_buffer_base_set($b, $base);
+event_buffer_enable($b, EV_READ);
+
+event_base_loop($base);
+
+
+
+?>
--- /dev/null
+++ b/ext/libevent/php_libevent.h
@@ -0,0 +1,68 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2008 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Antony Dovgal <tony@daylessday.org> |
+ | Arnaud Le Blanc <lbarnaud@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id: php_libevent.h 300687 2010-06-23 08:13:24Z tony2001 $ */
+
+#ifndef PHP_LIBEVENT_H
+#define PHP_LIBEVENT_H
+
+#define PHP_LIBEVENT_VERSION "0.0.4"
+
+extern zend_module_entry libevent_module_entry;
+#define phpext_libevent_ptr &libevent_module_entry
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+#ifndef zend_always_inline
+# if defined(__GNUC__)
+# define zend_always_inline inline __attribute__((always_inline))
+# elif defined(_MSC_VER)
+# define zend_always_inline __forceinline
+# else
+# define zend_always_inline inline
+# endif
+#endif
+
+#ifndef Z_ADDREF_P
+#define Z_ADDREF_P(pz) zval_addref_p(pz)
+static zend_always_inline zend_uint zval_addref_p(zval* pz) {
+ return ++pz->refcount;
+}
+#endif
+
+#ifndef Z_DELREF_P
+#define Z_DELREF_P(pz) zval_delref_p(pz)
+static zend_always_inline zend_uint zval_delref_p(zval* pz) {
+ return --pz->refcount;
+}
+#endif
+
+#endif /* PHP_LIBEVENT_H */
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */