@@ -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
286301static 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
289306static char * php_uv_map_resource_name (enum php_uv_resource_type type )
290307{
@@ -419,7 +436,7 @@ static inline int php_uv_common_init(php_uv_t **result, uv_loop_t *loop, enum ph
419436 {
420437 r = uv_check_init (loop , & uv -> uv .check );
421438 if (r ) {
422- php_error_docref (NULL TSRMLS_CC , E_ERROR , "uv_prepare_init failed ");
439+ php_error_docref (NULL TSRMLS_CC , E_ERROR , "uv_check_init failed ");
423440 goto cleanup ;
424441 }
425442
@@ -1231,6 +1248,7 @@ static int php_uv_do_callback2(zval **retval_ptr, php_uv_t *uv, zval ***params,
12311248}
12321249
12331250#ifdef ZTS
1251+
12341252static int php_uv_do_callback3 (zval * * retval_ptr , php_uv_t * uv , zval * * * params , int param_count , enum php_uv_callback_type type )
12351253{
12361254 int error = 0 ;
@@ -1262,9 +1280,17 @@ static int php_uv_do_callback3(zval **retval_ptr, php_uv_t *uv, zval ***params,
12621280 uv -> callback [type ]-> fcc .called_scope = NULL ;
12631281 uv -> callback [type ]-> fcc .object_ptr = ZEG -> This ;
12641282
1265- if (zend_call_function (& uv -> callback [type ]-> fci , & uv -> callback [type ]-> fcc TSRMLS_CC ) != SUCCESS ) {
1283+ zend_try {
1284+ if (zend_call_function (& uv -> callback [type ]-> fci , & uv -> callback [type ]-> fcc TSRMLS_CC ) != SUCCESS ) {
1285+ error = -1 ;
1286+ }
1287+
1288+ if (retval_ptr != NULL ) {
1289+ zval_ptr_dtor (retval_ptr );
1290+ }
1291+ } zend_catch {
12661292 error = -1 ;
1267- }
1293+ } zend_end_try ();
12681294
12691295 {
12701296 zend_op_array * ops = & uv -> callback [type ]-> fcc .function_handler -> op_array ;
@@ -1275,9 +1301,6 @@ static int php_uv_do_callback3(zval **retval_ptr, php_uv_t *uv, zval ***params,
12751301 }
12761302 }
12771303 }
1278- if (retval_ptr != NULL ) {
1279- zval_ptr_dtor (retval_ptr );
1280- }
12811304
12821305 php_request_shutdown (TSRMLS_C );
12831306 tsrm_set_interpreter_context (old );
@@ -2215,6 +2238,31 @@ static void php_uv_timer_cb(uv_timer_t *handle, int status)
22152238 zval_ptr_dtor (& client );
22162239}
22172240
2241+ static void php_uv_signal_cb (uv_signal_t * handle , int sig_num )
2242+ {
2243+ zval * retval_ptr , * zsig , * client = NULL ;
2244+ zval * * params [2 ];
2245+ php_uv_t * uv = (php_uv_t * )handle -> data ;
2246+ TSRMLS_FETCH_FROM_CTX (uv -> thread_ctx );
2247+
2248+ MAKE_STD_ZVAL (zsig );
2249+ ZVAL_LONG (zsig , sig_num );
2250+ MAKE_STD_ZVAL (client );
2251+ ZVAL_RESOURCE (client , uv -> resource_id );
2252+ zend_list_addref (uv -> resource_id );
2253+
2254+ params [0 ] = & client ;
2255+ params [1 ] = & zsig ;
2256+
2257+ php_uv_do_callback2 (& retval_ptr , uv , params , 2 , PHP_UV_SIGNAL_CB TSRMLS_CC );
2258+
2259+ if (retval_ptr != NULL ) {
2260+ zval_ptr_dtor (& retval_ptr );
2261+ }
2262+ zval_ptr_dtor (& zsig );
2263+ zval_ptr_dtor (& client );
2264+ }
2265+
22182266static inline uv_stream_t * php_uv_get_current_stream (php_uv_t * uv )
22192267{
22202268 uv_stream_t * stream ;
@@ -2688,6 +2736,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_run, 0, 0, 1)
26882736 ZEND_ARG_INFO (0 , loop )
26892737ZEND_END_ARG_INFO ()
26902738
2739+ ZEND_BEGIN_ARG_INFO_EX (arginfo_uv_stop , 0 , 0 , 1 )
2740+ ZEND_ARG_INFO (0 , loop )
2741+ ZEND_END_ARG_INFO ()
2742+
26912743ZEND_BEGIN_ARG_INFO_EX (arginfo_uv_loop_delete , 0 , 0 , 1 )
26922744 ZEND_ARG_INFO (0 , loop )
26932745ZEND_END_ARG_INFO ()
@@ -3337,6 +3389,20 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_uv_poll_stop, 0, 0, 1)
33373389 ZEND_ARG_INFO (0 , handle )
33383390ZEND_END_ARG_INFO ()
33393391
3392+ ZEND_BEGIN_ARG_INFO_EX (arginfo_uv_signal_init , 0 , 0 , 1 )
3393+ ZEND_ARG_INFO (0 , loop )
3394+ ZEND_END_ARG_INFO ()
3395+
3396+ ZEND_BEGIN_ARG_INFO_EX (arginfo_uv_signal_start , 0 , 0 , 3 )
3397+ ZEND_ARG_INFO (0 , sig_handle )
3398+ ZEND_ARG_INFO (0 , sig_callback )
3399+ ZEND_ARG_INFO (0 , sig_num )
3400+ ZEND_END_ARG_INFO ()
3401+
3402+ ZEND_BEGIN_ARG_INFO_EX (arginfo_uv_signal_stop , 0 , 0 , 1 )
3403+ ZEND_ARG_INFO (0 , sig_handle )
3404+ ZEND_END_ARG_INFO ()
3405+
33403406/* PHP Functions */
33413407
33423408/* {{{ proto void uv_unref(resource $uv_t)
@@ -3483,6 +3549,104 @@ PHP_FUNCTION(uv_run)
34833549}
34843550/* }}} */
34853551
3552+ /* {{{ proto void uv_stop([resource $uv_loop])
3553+ */
3554+ PHP_FUNCTION (uv_stop )
3555+ {
3556+ zval * zloop = NULL ;
3557+ uv_loop_t * loop ;
3558+
3559+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC ,
3560+ "|z" ,& zloop ) == FAILURE ) {
3561+ return ;
3562+ }
3563+ PHP_UV_FETCH_UV_DEFAULT_LOOP (loop , zloop );
3564+ uv_stop (loop );
3565+ }
3566+ /* }}} */
3567+
3568+ /* {{{ proto resource uv_signal_init([resource $uv_loop])
3569+ */
3570+ PHP_FUNCTION (uv_signal_init )
3571+ {
3572+ zval * zloop = NULL ;
3573+ uv_loop_t * loop ;
3574+ php_uv_t * uv ;
3575+
3576+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC ,
3577+ "|z" ,& zloop ) == FAILURE ) {
3578+ return ;
3579+ }
3580+
3581+ PHP_UV_FETCH_UV_DEFAULT_LOOP (loop , zloop );
3582+ PHP_UV_INIT_SIGNAL (uv , IS_UV_SIGNAL )
3583+
3584+ uv -> uv .signal .data = uv ;
3585+
3586+ ZVAL_RESOURCE (return_value , uv -> resource_id );
3587+ }
3588+ /* }}} */
3589+
3590+ /* {{{ proto void uv_signal_start(resource $sig_handle, callable $sig_callback, int $sig_num)
3591+ */
3592+ PHP_FUNCTION (uv_signal_start )
3593+ {
3594+ zval * sig_handle ;
3595+ long sig_num ;
3596+ php_uv_t * uv ;
3597+ zend_fcall_info fci = empty_fcall_info ;
3598+ zend_fcall_info_cache fcc = empty_fcall_info_cache ;
3599+ php_uv_cb_t * cb ;
3600+
3601+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC ,
3602+ "rfl" , & sig_handle , & fci , & fcc , & sig_num ) == FAILURE ) {
3603+ return ;
3604+ }
3605+
3606+ ZEND_FETCH_RESOURCE (uv , php_uv_t * , & sig_handle , -1 , PHP_UV_RESOURCE_NAME , uv_resource_handle );
3607+
3608+ PHP_UV_TYPE_CHECK (uv , IS_UV_SIGNAL );
3609+
3610+ if (uv_is_active ((uv_handle_t * )& uv -> uv .signal )) {
3611+ php_error_docref (NULL TSRMLS_CC , E_NOTICE , "passed uv signal resource has been started. you don't have to call this method" );
3612+ RETURN_FALSE ;
3613+ }
3614+
3615+ zend_list_addref (uv -> resource_id );
3616+ php_uv_cb_init (& cb , uv , & fci , & fcc , PHP_UV_SIGNAL_CB );
3617+
3618+ uv_signal_start ((uv_signal_t * )& uv -> uv .signal , php_uv_signal_cb , sig_num );
3619+ }
3620+ /* }}} */
3621+
3622+ /* {{{ proto int uv_signal_stop(resource $sig_handle)
3623+ */
3624+ PHP_FUNCTION (uv_signal_stop )
3625+ {
3626+ zval * sig_handle ;
3627+ php_uv_t * uv ;
3628+ int r = 0 ;
3629+
3630+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC ,
3631+ "r" , & sig_handle ) == FAILURE ) {
3632+ return ;
3633+ }
3634+
3635+ ZEND_FETCH_RESOURCE (uv , php_uv_t * , & sig_handle , -1 , PHP_UV_RESOURCE_NAME , uv_resource_handle );
3636+
3637+ PHP_UV_TYPE_CHECK (uv , IS_UV_SIGNAL );
3638+
3639+ if (!uv_is_active ((uv_handle_t * )& uv -> uv .signal )) {
3640+ php_error_docref (NULL TSRMLS_CC , E_NOTICE , "passed uv signal resource has been stopped. you don't have to call this method" );
3641+ RETURN_FALSE ;
3642+ }
3643+
3644+ r = uv_signal_stop ((uv_signal_t * )& uv -> uv .signal );
3645+
3646+ RETURN_LONG (r );
3647+ }
3648+ /* }}} */
3649+
34863650/* {{{ proto long uv_run_once([resource $uv_loop])
34873651*/
34883652PHP_FUNCTION (uv_run_once )
@@ -6439,6 +6603,7 @@ static zend_function_entry uv_functions[] = {
64396603 PHP_FE (uv_unref , arginfo_uv_unref )
64406604 PHP_FE (uv_loop_new , NULL )
64416605 PHP_FE (uv_default_loop , NULL )
6606+ PHP_FE (uv_stop , arginfo_uv_stop )
64426607 PHP_FE (uv_run , arginfo_uv_run )
64436608 PHP_FE (uv_run_once , arginfo_uv_run_once )
64446609 PHP_FE (uv_ip4_addr , arginfo_uv_ip4_addr )
@@ -6601,6 +6766,10 @@ static zend_function_entry uv_functions[] = {
66016766 PHP_FE (uv_cwd , NULL )
66026767 PHP_FE (uv_chdir , arginfo_uv_chdir )
66036768 PHP_FE (uv_resident_set_memory , NULL )
6769+ /* signal handling */
6770+ PHP_FE (uv_signal_init , arginfo_uv_signal_init )
6771+ PHP_FE (uv_signal_start , arginfo_uv_signal_start )
6772+ PHP_FE (uv_signal_stop , arginfo_uv_signal_stop )
66046773 /* http parser */
66056774 PHP_FE (uv_http_parser_init , arginfo_uv_http_parser_init )
66066775 PHP_FE (uv_http_parser_execute , arginfo_uv_http_parser_execute )
0 commit comments