Skip to content

Commit 1e32c24

Browse files
committed
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());
1 parent 096eedc commit 1e32c24

File tree

3 files changed

+208
-2
lines changed

3 files changed

+208
-2
lines changed

php_uv.c

100644100755
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,21 @@ zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0
6565
TSRMLS_SET_CTX(uv->thread_ctx); \
6666
uv->resource_id = PHP_UV_LIST_INSERT(uv, uv_resource_handle); \
6767

68+
#define PHP_UV_INIT_SIGNAL(uv, uv_type) \
69+
uv = (php_uv_t *)emalloc(sizeof(php_uv_t)); \
70+
if (!uv) { \
71+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "emalloc failed"); \
72+
RETURN_FALSE; \
73+
} \
74+
if (uv_signal_init(loop, &uv->uv.signal)) { \
75+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uv_signal_init failed");\
76+
RETURN_FALSE;\
77+
} \
78+
uv->type = uv_type; \
79+
PHP_UV_INIT_ZVALS(uv) \
80+
TSRMLS_SET_CTX(uv->thread_ctx); \
81+
uv->resource_id = PHP_UV_LIST_INSERT(uv, uv_resource_handle); \
82+
6883
#define PHP_UV_INIT_CONNECT(req, uv) \
6984
req = (uv_connect_t*)emalloc(sizeof(uv_connect_t)); \
7085
req->data = uv;
@@ -285,6 +300,8 @@ static void php_uv_timer_cb(uv_timer_t *handle, int status);
285300

286301
static void php_uv_idle_cb(uv_timer_t *handle, int status);
287302

303+
static void php_uv_signal_cb(uv_signal_t *handle, int sig_num);
304+
288305

289306
static char *php_uv_map_resource_name(enum php_uv_resource_type type)
290307
{
@@ -2215,6 +2232,31 @@ static void php_uv_timer_cb(uv_timer_t *handle, int status)
22152232
zval_ptr_dtor(&client);
22162233
}
22172234

2235+
static void php_uv_signal_cb(uv_signal_t *handle, int sig_num)
2236+
{
2237+
zval *retval_ptr, *zsig, *client= NULL;
2238+
zval **params[2];
2239+
php_uv_t *uv = (php_uv_t*)handle->data;
2240+
TSRMLS_FETCH_FROM_CTX(uv->thread_ctx);
2241+
2242+
MAKE_STD_ZVAL(zsig);
2243+
ZVAL_LONG(zsig, sig_num);
2244+
MAKE_STD_ZVAL(client);
2245+
ZVAL_RESOURCE(client, uv->resource_id);
2246+
zend_list_addref(uv->resource_id);
2247+
2248+
params[0] = &client;
2249+
params[1] = &zsig;
2250+
2251+
php_uv_do_callback2(&retval_ptr, uv, params, 2, PHP_UV_SIGNAL_CB TSRMLS_CC);
2252+
2253+
if (retval_ptr != NULL) {
2254+
zval_ptr_dtor(&retval_ptr);
2255+
}
2256+
zval_ptr_dtor(&zsig);
2257+
zval_ptr_dtor(&client);
2258+
}
2259+
22182260
static inline uv_stream_t* php_uv_get_current_stream(php_uv_t *uv)
22192261
{
22202262
uv_stream_t *stream;
@@ -3341,6 +3383,20 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_poll_stop, 0, 0, 1)
33413383
ZEND_ARG_INFO(0, handle)
33423384
ZEND_END_ARG_INFO()
33433385

3386+
ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_signal_init, 0, 0, 1)
3387+
ZEND_ARG_INFO(0, loop)
3388+
ZEND_END_ARG_INFO()
3389+
3390+
ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_signal_start, 0, 0, 3)
3391+
ZEND_ARG_INFO(0, sig_handle)
3392+
ZEND_ARG_INFO(0, sig_callback)
3393+
ZEND_ARG_INFO(0, sig_num)
3394+
ZEND_END_ARG_INFO()
3395+
3396+
ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_signal_stop, 0, 0, 1)
3397+
ZEND_ARG_INFO(0, sig_handle)
3398+
ZEND_END_ARG_INFO()
3399+
33443400
/* PHP Functions */
33453401

33463402
/* {{{ proto void uv_unref(resource $uv_t)
@@ -3503,6 +3559,88 @@ PHP_FUNCTION(uv_stop)
35033559
}
35043560
/* }}} */
35053561

3562+
/* {{{ proto resource uv_signal_init([resource $uv_loop])
3563+
*/
3564+
PHP_FUNCTION(uv_signal_init)
3565+
{
3566+
zval *zloop = NULL;
3567+
uv_loop_t *loop;
3568+
php_uv_t *uv;
3569+
3570+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
3571+
"|z",&zloop) == FAILURE) {
3572+
return;
3573+
}
3574+
3575+
PHP_UV_FETCH_UV_DEFAULT_LOOP(loop, zloop);
3576+
PHP_UV_INIT_SIGNAL(uv, IS_UV_SIGNAL)
3577+
3578+
uv->uv.signal.data = uv;
3579+
3580+
ZVAL_RESOURCE(return_value, uv->resource_id);
3581+
}
3582+
/* }}} */
3583+
3584+
/* {{{ proto void uv_signal_start(resource $sig_handle, callable $sig_callback, int $sig_num)
3585+
*/
3586+
PHP_FUNCTION(uv_signal_start)
3587+
{
3588+
zval *sig_handle;
3589+
long sig_num;
3590+
php_uv_t *uv;
3591+
zend_fcall_info fci = empty_fcall_info;
3592+
zend_fcall_info_cache fcc = empty_fcall_info_cache;
3593+
php_uv_cb_t *cb;
3594+
3595+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
3596+
"rfl", &sig_handle, &fci, &fcc, &sig_num) == FAILURE) {
3597+
return;
3598+
}
3599+
3600+
ZEND_FETCH_RESOURCE(uv, php_uv_t *, &sig_handle, -1, PHP_UV_RESOURCE_NAME, uv_resource_handle);
3601+
3602+
PHP_UV_TYPE_CHECK(uv, IS_UV_SIGNAL);
3603+
3604+
if (uv_is_active((uv_handle_t*)&uv->uv.signal)) {
3605+
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "passed uv signal resource has been started. you don't have to call this method");
3606+
RETURN_FALSE;
3607+
}
3608+
3609+
zend_list_addref(uv->resource_id);
3610+
php_uv_cb_init(&cb, uv, &fci, &fcc, PHP_UV_SIGNAL_CB);
3611+
3612+
uv_signal_start((uv_signal_t*)&uv->uv.signal, php_uv_signal_cb, sig_num);
3613+
}
3614+
/* }}} */
3615+
3616+
/* {{{ proto int uv_signal_stop(resource $sig_handle)
3617+
*/
3618+
PHP_FUNCTION(uv_signal_stop)
3619+
{
3620+
zval *sig_handle;
3621+
php_uv_t *uv;
3622+
int r = 0;
3623+
3624+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
3625+
"r", &sig_handle) == FAILURE) {
3626+
return;
3627+
}
3628+
3629+
ZEND_FETCH_RESOURCE(uv, php_uv_t *, &sig_handle, -1, PHP_UV_RESOURCE_NAME, uv_resource_handle);
3630+
3631+
PHP_UV_TYPE_CHECK(uv, IS_UV_SIGNAL);
3632+
3633+
if (!uv_is_active((uv_handle_t*)&uv->uv.signal)) {
3634+
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "passed uv signal resource has been stopped. you don't have to call this method");
3635+
RETURN_FALSE;
3636+
}
3637+
3638+
r = uv_signal_stop((uv_signal_t*)&uv->uv.signal);
3639+
3640+
RETURN_LONG(r);
3641+
}
3642+
/* }}} */
3643+
35063644
/* {{{ proto long uv_run_once([resource $uv_loop])
35073645
*/
35083646
PHP_FUNCTION(uv_run_once)
@@ -6622,6 +6760,10 @@ static zend_function_entry uv_functions[] = {
66226760
PHP_FE(uv_cwd, NULL)
66236761
PHP_FE(uv_chdir, arginfo_uv_chdir)
66246762
PHP_FE(uv_resident_set_memory, NULL)
6763+
/* signal handling */
6764+
PHP_FE(uv_signal_init, arginfo_uv_signal_init)
6765+
PHP_FE(uv_signal_start, arginfo_uv_signal_start)
6766+
PHP_FE(uv_signal_stop, arginfo_uv_signal_stop)
66256767
/* http parser */
66266768
PHP_FE(uv_http_parser_init, arginfo_uv_http_parser_init)
66276769
PHP_FE(uv_http_parser_execute, arginfo_uv_http_parser_execute)

php_uv.h

100644100755
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ enum php_uv_resource_type{
8989
IS_UV_TTY = 16,
9090
IS_UV_FS_POLL = 17,
9191
IS_UV_POLL = 18,
92-
IS_UV_MAX = 19
92+
IS_UV_SIGNAL = 19,
93+
IS_UV_MAX = 20
9394
};
9495

9596
enum php_uv_callback_type{
@@ -116,7 +117,8 @@ enum php_uv_callback_type{
116117
PHP_UV_FS_EVENT_CB = 20,
117118
PHP_UV_FS_POLL_CB = 21,
118119
PHP_UV_POLL_CB = 22,
119-
PHP_UV_CB_MAX = 23
120+
PHP_UV_SIGNAL_CB = 23,
121+
PHP_UV_CB_MAX = 24
120122
};
121123

122124
typedef struct {
@@ -152,6 +154,7 @@ typedef struct {
152154
uv_tty_t tty;
153155
uv_fs_poll_t fs_poll;
154156
uv_poll_t poll;
157+
uv_signal_t signal;
155158
} uv;
156159
char *buffer;
157160
zval *address;

uv.c

100644100755
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,67 @@ static int php_uv_class_init(TSRMLS_D)
6666
zend_declare_class_constant_long(uv_class_entry, "S_IROTH", sizeof("S_IROTH")-1, S_IROTH TSRMLS_CC);
6767
zend_declare_class_constant_long(uv_class_entry, "S_IWOTH", sizeof("S_IWOTH")-1, S_IWOTH TSRMLS_CC);
6868
zend_declare_class_constant_long(uv_class_entry, "S_IXOTH", sizeof("S_IXOTH")-1, S_IXOTH TSRMLS_CC);
69+
70+
/* Non-windows Signal Constants */
71+
zend_declare_class_constant_long(uv_class_entry, "SIG_IGN", sizeof("SIG_IGN")-1, (long) SIG_IGN TSRMLS_CC);
72+
zend_declare_class_constant_long(uv_class_entry, "SIG_DFL", sizeof("SIG_DFL")-1, (long) SIG_DFL TSRMLS_CC);
73+
zend_declare_class_constant_long(uv_class_entry, "SIG_ERR", sizeof("SIG_ERR")-1, (long) SIG_ERR TSRMLS_CC);
74+
zend_declare_class_constant_long(uv_class_entry, "SIGHUP", sizeof("SIGHUP")-1, (long) SIGHUP TSRMLS_CC);
75+
zend_declare_class_constant_long(uv_class_entry, "SIGINT", sizeof("SIGINT")-1, (long) SIGINT TSRMLS_CC);
76+
zend_declare_class_constant_long(uv_class_entry, "SIGQUIT", sizeof("SIGQUIT")-1, (long) SIGQUIT TSRMLS_CC);
77+
zend_declare_class_constant_long(uv_class_entry, "SIGILL", sizeof("SIGILL")-1, (long) SIGILL TSRMLS_CC);
78+
zend_declare_class_constant_long(uv_class_entry, "SIGTRAP", sizeof("SIGTRAP")-1, (long) SIGTRAP TSRMLS_CC);
79+
zend_declare_class_constant_long(uv_class_entry, "SIGABRT", sizeof("SIGABRT")-1, (long) SIGABRT TSRMLS_CC);
80+
#ifdef SIGIOT
81+
zend_declare_class_constant_long(uv_class_entry, "SIGIOT", sizeof("SIGIOT")-1, (long) SIGIOT TSRMLS_CC);
82+
#endif
83+
zend_declare_class_constant_long(uv_class_entry, "SIGBUS", sizeof("SIGBUS")-1, (long) SIGBUS TSRMLS_CC);
84+
zend_declare_class_constant_long(uv_class_entry, "SIGFPE", sizeof("SIGFPE")-1, (long) SIGFPE TSRMLS_CC);
85+
zend_declare_class_constant_long(uv_class_entry, "SIGKILL", sizeof("SIGKILL")-1, (long) SIGKILL TSRMLS_CC);
86+
zend_declare_class_constant_long(uv_class_entry, "SIGUSR1", sizeof("SIGUSR1")-1, (long) SIGUSR1 TSRMLS_CC);
87+
zend_declare_class_constant_long(uv_class_entry, "SIGSEGV", sizeof("SIGSEGV")-1, (long) SIGSEGV TSRMLS_CC);
88+
zend_declare_class_constant_long(uv_class_entry, "SIGUSR2", sizeof("SIGUSR2")-1, (long) SIGUSR2 TSRMLS_CC);
89+
zend_declare_class_constant_long(uv_class_entry, "SIGPIPE", sizeof("SIGPIPE")-1, (long) SIGPIPE TSRMLS_CC);
90+
zend_declare_class_constant_long(uv_class_entry, "SIGALRM", sizeof("SIGALRM")-1, (long) SIGALRM TSRMLS_CC);
91+
zend_declare_class_constant_long(uv_class_entry, "SIGTERM", sizeof("SIGTERM")-1, (long) SIGTERM TSRMLS_CC);
92+
#ifdef SIGSTKFLT
93+
zend_declare_class_constant_long(uv_class_entry, "SIGSTKFLT",sizeof("SIGSTKFLT")-1, (long) SIGSTKFLT TSRMLS_CC);
94+
#endif
95+
#ifdef SIGCLD
96+
zend_declare_class_constant_long(uv_class_entry, "SIGCLD", sizeof("SIGCLD")-1, (long) SIGCLD TSRMLS_CC);
97+
#endif
98+
#ifdef SIGCHLD
99+
zend_declare_class_constant_long(uv_class_entry, "SIGCHLD", sizeof("SIGCHLD")-1, (long) SIGCHLD TSRMLS_CC);
100+
#endif
101+
zend_declare_class_constant_long(uv_class_entry, "SIGCONT", sizeof("SIGCONT")-1, (long) SIGCONT TSRMLS_CC);
102+
zend_declare_class_constant_long(uv_class_entry, "SIGSTOP", sizeof("SIGSTOP")-1, (long) SIGSTOP TSRMLS_CC);
103+
zend_declare_class_constant_long(uv_class_entry, "SIGTSTP", sizeof("SIGTSTP")-1, (long) SIGTSTP TSRMLS_CC);
104+
zend_declare_class_constant_long(uv_class_entry, "SIGTTIN", sizeof("SIGTTIN")-1, (long) SIGTTIN TSRMLS_CC);
105+
zend_declare_class_constant_long(uv_class_entry, "SIGTTOU", sizeof("SIGTTOU")-1, (long) SIGTTOU TSRMLS_CC);
106+
zend_declare_class_constant_long(uv_class_entry, "SIGURG", sizeof("SIGURG")-1, (long) SIGURG TSRMLS_CC);
107+
zend_declare_class_constant_long(uv_class_entry, "SIGXCPU", sizeof("SIGXCPU")-1, (long) SIGXCPU TSRMLS_CC);
108+
zend_declare_class_constant_long(uv_class_entry, "SIGXFSZ", sizeof("SIGXFSZ")-1, (long) SIGXFSZ TSRMLS_CC);
109+
zend_declare_class_constant_long(uv_class_entry, "SIGVTALRM",sizeof("SIGVTALRM")-1, (long) SIGVTALRM TSRMLS_CC);
110+
zend_declare_class_constant_long(uv_class_entry, "SIGPROF", sizeof("SIGPROF")-1, (long) SIGPROF TSRMLS_CC);
111+
zend_declare_class_constant_long(uv_class_entry, "SIGWINCH", sizeof("SIGWINCH")-1, (long) SIGWINCH TSRMLS_CC);
112+
#ifdef SIGPOLL
113+
zend_declare_class_constant_long(uv_class_entry, "SIGPOLL", sizeof("SIGPOLL")-1, (long) SIGPOLL TSRMLS_CC);
114+
#endif
115+
zend_declare_class_constant_long(uv_class_entry, "SIGIO", sizeof("SIGIO")-1, (long) SIGIO TSRMLS_CC);
116+
#ifdef SIGPWR
117+
zend_declare_class_constant_long(uv_class_entry, "SIGPWR", sizeof("SIGPWR")-1, (long) SIGPWR TSRMLS_CC);
118+
#endif
119+
#ifdef SIGSYS
120+
zend_declare_class_constant_long(uv_class_entry, "SIGSYS", sizeof("SIGSYS")-1, (long) SIGSYS TSRMLS_CC);
121+
zend_declare_class_constant_long(uv_class_entry, "SIGBABY", sizeof("SIGBABY")-1, (long) SIGSYS TSRMLS_CC);
122+
#endif
123+
124+
#else
125+
/* Windows Signal Constants */
126+
zend_declare_class_constant_long(uv_class_entry, "SIGBREAK", sizeof("SIGBREAK")-1, (long) SIGBREAK TSRMLS_CC);
127+
zend_declare_class_constant_long(uv_class_entry, "SIGINT", sizeof("SIGINT")-1, (long) SIGINT TSRMLS_CC);
128+
zend_declare_class_constant_long(uv_class_entry, "SIGHUP", sizeof("SIGHUP")-1, (long) SIGHUP TSRMLS_CC);
129+
zend_declare_class_constant_long(uv_class_entry, "SIGWINCH", sizeof("SIGWINCH")-1, (long) SIGWINCH TSRMLS_CC);
69130
#endif
70131

71132
zend_declare_class_constant_long(uv_class_entry, "AF_INET", sizeof("AF_INET")-1, AF_INET TSRMLS_CC);

0 commit comments

Comments
 (0)