mirror of
https://github.com/danog/ext-uv.git
synced 2024-11-30 04:29:01 +01:00
Add signal handling support
- resource uv_signal_init([resource $loop]) - void uv_signal_start(resource $sigHandle, callable $onSignal, int $signal) - void uv_signal_stop($signalResource) Example: <?php $sigHandle = uv_signal_init(); $onSigint = function($sigHandle, $sigNum) { printf("Caught signal: %d\n", $sigNum); uv_signal_stop($sigHandle); uv_stop(); }; uv_signal_start($sigHandle, $onSigint, UV::SIGINT); uv_run(); New signal constants (these vary by OS): <?php $refl = new ReflectionClass('UV'); print_r($refl->getConstants());
This commit is contained in:
parent
096eedc215
commit
1e32c24608
142
php_uv.c
Normal file → Executable file
142
php_uv.c
Normal file → Executable file
@ -65,6 +65,21 @@ zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0
|
||||
TSRMLS_SET_CTX(uv->thread_ctx); \
|
||||
uv->resource_id = PHP_UV_LIST_INSERT(uv, uv_resource_handle); \
|
||||
|
||||
#define PHP_UV_INIT_SIGNAL(uv, uv_type) \
|
||||
uv = (php_uv_t *)emalloc(sizeof(php_uv_t)); \
|
||||
if (!uv) { \
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "emalloc failed"); \
|
||||
RETURN_FALSE; \
|
||||
} \
|
||||
if (uv_signal_init(loop, &uv->uv.signal)) { \
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uv_signal_init failed");\
|
||||
RETURN_FALSE;\
|
||||
} \
|
||||
uv->type = uv_type; \
|
||||
PHP_UV_INIT_ZVALS(uv) \
|
||||
TSRMLS_SET_CTX(uv->thread_ctx); \
|
||||
uv->resource_id = PHP_UV_LIST_INSERT(uv, uv_resource_handle); \
|
||||
|
||||
#define PHP_UV_INIT_CONNECT(req, uv) \
|
||||
req = (uv_connect_t*)emalloc(sizeof(uv_connect_t)); \
|
||||
req->data = uv;
|
||||
@ -285,6 +300,8 @@ static void php_uv_timer_cb(uv_timer_t *handle, int status);
|
||||
|
||||
static void php_uv_idle_cb(uv_timer_t *handle, int status);
|
||||
|
||||
static void php_uv_signal_cb(uv_signal_t *handle, int sig_num);
|
||||
|
||||
|
||||
static char *php_uv_map_resource_name(enum php_uv_resource_type type)
|
||||
{
|
||||
@ -2215,6 +2232,31 @@ static void php_uv_timer_cb(uv_timer_t *handle, int status)
|
||||
zval_ptr_dtor(&client);
|
||||
}
|
||||
|
||||
static void php_uv_signal_cb(uv_signal_t *handle, int sig_num)
|
||||
{
|
||||
zval *retval_ptr, *zsig, *client= NULL;
|
||||
zval **params[2];
|
||||
php_uv_t *uv = (php_uv_t*)handle->data;
|
||||
TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
|
||||
|
||||
MAKE_STD_ZVAL(zsig);
|
||||
ZVAL_LONG(zsig, sig_num);
|
||||
MAKE_STD_ZVAL(client);
|
||||
ZVAL_RESOURCE(client, uv->resource_id);
|
||||
zend_list_addref(uv->resource_id);
|
||||
|
||||
params[0] = &client;
|
||||
params[1] = &zsig;
|
||||
|
||||
php_uv_do_callback2(&retval_ptr, uv, params, 2, PHP_UV_SIGNAL_CB TSRMLS_CC);
|
||||
|
||||
if (retval_ptr != NULL) {
|
||||
zval_ptr_dtor(&retval_ptr);
|
||||
}
|
||||
zval_ptr_dtor(&zsig);
|
||||
zval_ptr_dtor(&client);
|
||||
}
|
||||
|
||||
static inline uv_stream_t* php_uv_get_current_stream(php_uv_t *uv)
|
||||
{
|
||||
uv_stream_t *stream;
|
||||
@ -3341,6 +3383,20 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_poll_stop, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, handle)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_signal_init, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, loop)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_signal_start, 0, 0, 3)
|
||||
ZEND_ARG_INFO(0, sig_handle)
|
||||
ZEND_ARG_INFO(0, sig_callback)
|
||||
ZEND_ARG_INFO(0, sig_num)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_signal_stop, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, sig_handle)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
/* PHP Functions */
|
||||
|
||||
/* {{{ proto void uv_unref(resource $uv_t)
|
||||
@ -3503,6 +3559,88 @@ PHP_FUNCTION(uv_stop)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource uv_signal_init([resource $uv_loop])
|
||||
*/
|
||||
PHP_FUNCTION(uv_signal_init)
|
||||
{
|
||||
zval *zloop = NULL;
|
||||
uv_loop_t *loop;
|
||||
php_uv_t *uv;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
|
||||
"|z",&zloop) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
PHP_UV_FETCH_UV_DEFAULT_LOOP(loop, zloop);
|
||||
PHP_UV_INIT_SIGNAL(uv, IS_UV_SIGNAL)
|
||||
|
||||
uv->uv.signal.data = uv;
|
||||
|
||||
ZVAL_RESOURCE(return_value, uv->resource_id);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto void uv_signal_start(resource $sig_handle, callable $sig_callback, int $sig_num)
|
||||
*/
|
||||
PHP_FUNCTION(uv_signal_start)
|
||||
{
|
||||
zval *sig_handle;
|
||||
long sig_num;
|
||||
php_uv_t *uv;
|
||||
zend_fcall_info fci = empty_fcall_info;
|
||||
zend_fcall_info_cache fcc = empty_fcall_info_cache;
|
||||
php_uv_cb_t *cb;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
|
||||
"rfl", &sig_handle, &fci, &fcc, &sig_num) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(uv, php_uv_t *, &sig_handle, -1, PHP_UV_RESOURCE_NAME, uv_resource_handle);
|
||||
|
||||
PHP_UV_TYPE_CHECK(uv, IS_UV_SIGNAL);
|
||||
|
||||
if (uv_is_active((uv_handle_t*)&uv->uv.signal)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "passed uv signal resource has been started. you don't have to call this method");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
zend_list_addref(uv->resource_id);
|
||||
php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_SIGNAL_CB);
|
||||
|
||||
uv_signal_start((uv_signal_t*)&uv->uv.signal, php_uv_signal_cb, sig_num);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int uv_signal_stop(resource $sig_handle)
|
||||
*/
|
||||
PHP_FUNCTION(uv_signal_stop)
|
||||
{
|
||||
zval *sig_handle;
|
||||
php_uv_t *uv;
|
||||
int r = 0;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
|
||||
"r", &sig_handle) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(uv, php_uv_t *, &sig_handle, -1, PHP_UV_RESOURCE_NAME, uv_resource_handle);
|
||||
|
||||
PHP_UV_TYPE_CHECK(uv, IS_UV_SIGNAL);
|
||||
|
||||
if (!uv_is_active((uv_handle_t*)&uv->uv.signal)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "passed uv signal resource has been stopped. you don't have to call this method");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
r = uv_signal_stop((uv_signal_t*)&uv->uv.signal);
|
||||
|
||||
RETURN_LONG(r);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto long uv_run_once([resource $uv_loop])
|
||||
*/
|
||||
PHP_FUNCTION(uv_run_once)
|
||||
@ -6622,6 +6760,10 @@ static zend_function_entry uv_functions[] = {
|
||||
PHP_FE(uv_cwd, NULL)
|
||||
PHP_FE(uv_chdir, arginfo_uv_chdir)
|
||||
PHP_FE(uv_resident_set_memory, NULL)
|
||||
/* signal handling */
|
||||
PHP_FE(uv_signal_init, arginfo_uv_signal_init)
|
||||
PHP_FE(uv_signal_start, arginfo_uv_signal_start)
|
||||
PHP_FE(uv_signal_stop, arginfo_uv_signal_stop)
|
||||
/* http parser */
|
||||
PHP_FE(uv_http_parser_init, arginfo_uv_http_parser_init)
|
||||
PHP_FE(uv_http_parser_execute, arginfo_uv_http_parser_execute)
|
||||
|
7
php_uv.h
Normal file → Executable file
7
php_uv.h
Normal file → Executable file
@ -89,7 +89,8 @@ enum php_uv_resource_type{
|
||||
IS_UV_TTY = 16,
|
||||
IS_UV_FS_POLL = 17,
|
||||
IS_UV_POLL = 18,
|
||||
IS_UV_MAX = 19
|
||||
IS_UV_SIGNAL = 19,
|
||||
IS_UV_MAX = 20
|
||||
};
|
||||
|
||||
enum php_uv_callback_type{
|
||||
@ -116,7 +117,8 @@ enum php_uv_callback_type{
|
||||
PHP_UV_FS_EVENT_CB = 20,
|
||||
PHP_UV_FS_POLL_CB = 21,
|
||||
PHP_UV_POLL_CB = 22,
|
||||
PHP_UV_CB_MAX = 23
|
||||
PHP_UV_SIGNAL_CB = 23,
|
||||
PHP_UV_CB_MAX = 24
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@ -152,6 +154,7 @@ typedef struct {
|
||||
uv_tty_t tty;
|
||||
uv_fs_poll_t fs_poll;
|
||||
uv_poll_t poll;
|
||||
uv_signal_t signal;
|
||||
} uv;
|
||||
char *buffer;
|
||||
zval *address;
|
||||
|
61
uv.c
Normal file → Executable file
61
uv.c
Normal file → Executable file
@ -66,6 +66,67 @@ static int php_uv_class_init(TSRMLS_D)
|
||||
zend_declare_class_constant_long(uv_class_entry, "S_IROTH", sizeof("S_IROTH")-1, S_IROTH TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "S_IWOTH", sizeof("S_IWOTH")-1, S_IWOTH TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "S_IXOTH", sizeof("S_IXOTH")-1, S_IXOTH TSRMLS_CC);
|
||||
|
||||
/* Non-windows Signal Constants */
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIG_IGN", sizeof("SIG_IGN")-1, (long) SIG_IGN TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIG_DFL", sizeof("SIG_DFL")-1, (long) SIG_DFL TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIG_ERR", sizeof("SIG_ERR")-1, (long) SIG_ERR TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGHUP", sizeof("SIGHUP")-1, (long) SIGHUP TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGINT", sizeof("SIGINT")-1, (long) SIGINT TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGQUIT", sizeof("SIGQUIT")-1, (long) SIGQUIT TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGILL", sizeof("SIGILL")-1, (long) SIGILL TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGTRAP", sizeof("SIGTRAP")-1, (long) SIGTRAP TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGABRT", sizeof("SIGABRT")-1, (long) SIGABRT TSRMLS_CC);
|
||||
#ifdef SIGIOT
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGIOT", sizeof("SIGIOT")-1, (long) SIGIOT TSRMLS_CC);
|
||||
#endif
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGBUS", sizeof("SIGBUS")-1, (long) SIGBUS TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGFPE", sizeof("SIGFPE")-1, (long) SIGFPE TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGKILL", sizeof("SIGKILL")-1, (long) SIGKILL TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGUSR1", sizeof("SIGUSR1")-1, (long) SIGUSR1 TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGSEGV", sizeof("SIGSEGV")-1, (long) SIGSEGV TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGUSR2", sizeof("SIGUSR2")-1, (long) SIGUSR2 TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGPIPE", sizeof("SIGPIPE")-1, (long) SIGPIPE TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGALRM", sizeof("SIGALRM")-1, (long) SIGALRM TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGTERM", sizeof("SIGTERM")-1, (long) SIGTERM TSRMLS_CC);
|
||||
#ifdef SIGSTKFLT
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGSTKFLT",sizeof("SIGSTKFLT")-1, (long) SIGSTKFLT TSRMLS_CC);
|
||||
#endif
|
||||
#ifdef SIGCLD
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGCLD", sizeof("SIGCLD")-1, (long) SIGCLD TSRMLS_CC);
|
||||
#endif
|
||||
#ifdef SIGCHLD
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGCHLD", sizeof("SIGCHLD")-1, (long) SIGCHLD TSRMLS_CC);
|
||||
#endif
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGCONT", sizeof("SIGCONT")-1, (long) SIGCONT TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGSTOP", sizeof("SIGSTOP")-1, (long) SIGSTOP TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGTSTP", sizeof("SIGTSTP")-1, (long) SIGTSTP TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGTTIN", sizeof("SIGTTIN")-1, (long) SIGTTIN TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGTTOU", sizeof("SIGTTOU")-1, (long) SIGTTOU TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGURG", sizeof("SIGURG")-1, (long) SIGURG TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGXCPU", sizeof("SIGXCPU")-1, (long) SIGXCPU TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGXFSZ", sizeof("SIGXFSZ")-1, (long) SIGXFSZ TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGVTALRM",sizeof("SIGVTALRM")-1, (long) SIGVTALRM TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGPROF", sizeof("SIGPROF")-1, (long) SIGPROF TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGWINCH", sizeof("SIGWINCH")-1, (long) SIGWINCH TSRMLS_CC);
|
||||
#ifdef SIGPOLL
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGPOLL", sizeof("SIGPOLL")-1, (long) SIGPOLL TSRMLS_CC);
|
||||
#endif
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGIO", sizeof("SIGIO")-1, (long) SIGIO TSRMLS_CC);
|
||||
#ifdef SIGPWR
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGPWR", sizeof("SIGPWR")-1, (long) SIGPWR TSRMLS_CC);
|
||||
#endif
|
||||
#ifdef SIGSYS
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGSYS", sizeof("SIGSYS")-1, (long) SIGSYS TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGBABY", sizeof("SIGBABY")-1, (long) SIGSYS TSRMLS_CC);
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* Windows Signal Constants */
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGBREAK", sizeof("SIGBREAK")-1, (long) SIGBREAK TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGINT", sizeof("SIGINT")-1, (long) SIGINT TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGHUP", sizeof("SIGHUP")-1, (long) SIGHUP TSRMLS_CC);
|
||||
zend_declare_class_constant_long(uv_class_entry, "SIGWINCH", sizeof("SIGWINCH")-1, (long) SIGWINCH TSRMLS_CC);
|
||||
#endif
|
||||
|
||||
zend_declare_class_constant_long(uv_class_entry, "AF_INET", sizeof("AF_INET")-1, AF_INET TSRMLS_CC);
|
||||
|
Loading…
Reference in New Issue
Block a user