--- /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 | + | Arnaud Le Blanc | + +----------------------------------------------------------------------+ +*/ + +/* $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 + +#if PHP_VERSION_ID >= 50301 && (HAVE_SOCKETS || defined(COMPILE_DL_SOCKETS)) +# include "ext/sockets/php_sockets.h" +# define LIBEVENT_SOCKETS_SUPPORT +#endif + +#include + +#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 @@ + --- /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 | + | Arnaud Le Blanc | + +----------------------------------------------------------------------+ +*/ + +/* $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 + */