From c03ccfe78d6b13cab9546efb616a42a8f3e8a4e0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 6 Jul 2016 13:11:47 +0300 Subject: [PATCH] Asynchronous signal handling without TICKs. Squashed commit of the following: commit eda931df181060e202d2c664b4cba73a24afc6a1 Author: Dmitry Stogov Date: Wed Jul 6 10:53:30 2016 +0300 Replace pcntl.async_signals INI direcrive with pcntl_async_signals() function. commit bfbf7dd7c2389ebada6c4464b276d9fa33fcfb60 Author: Dmitry Stogov Date: Fri Jun 24 12:25:31 2016 +0300 Asynchronous signal handling without TICKs. --- NEWS | 3 +++ ext/pcntl/pcntl.c | 37 ++++++++++++++++++++++++++++++ ext/pcntl/php_pcntl.h | 2 ++ ext/pcntl/tests/async_signals.phpt | 25 ++++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 ext/pcntl/tests/async_signals.phpt diff --git a/NEWS b/NEWS index 778e7c3ebcb..470052bd2bc 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2016, PHP 7.1.0beta1 +- pcntl + . Implemented asynchronous signal handling without TICKS. (Dmitry) + 07 Jul 2016, PHP 7.1.0alpha3 - Core: diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index ef3c7fbe3dc..5a7747acf4e 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -148,6 +148,10 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_strerror, 0, 0, 1) ZEND_ARG_INFO(0, errno) ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_async_signals, 0, 0, 1) + ZEND_ARG_INFO(0, on) +ZEND_END_ARG_INFO() /* }}} */ const zend_function_entry pcntl_functions[] = { @@ -183,6 +187,7 @@ const zend_function_entry pcntl_functions[] = { #ifdef HAVE_WCONTINUED PHP_FE(pcntl_wifcontinued, arginfo_pcntl_wifcontinued) #endif + PHP_FE(pcntl_async_signals, arginfo_pcntl_async_signals) PHP_FE_END }; @@ -207,8 +212,11 @@ zend_module_entry pcntl_module_entry = { ZEND_GET_MODULE(pcntl) #endif +static void (*orig_interrupt_function)(zend_execute_data *execute_data); + static void pcntl_signal_handler(int); static void pcntl_signal_dispatch(); +static void pcntl_interrupt_function(zend_execute_data *execute_data); void php_register_signal_constants(INIT_FUNC_ARGS) { @@ -506,6 +514,7 @@ PHP_RINIT_FUNCTION(pcntl) { zend_hash_init(&PCNTL_G(php_signal_table), 16, NULL, ZVAL_PTR_DTOR, 0); PCNTL_G(head) = PCNTL_G(tail) = PCNTL_G(spares) = NULL; + PCNTL_G(async_signals) = 0; return SUCCESS; } @@ -514,6 +523,8 @@ PHP_MINIT_FUNCTION(pcntl) php_register_signal_constants(INIT_FUNC_ARGS_PASSTHRU); php_pcntl_register_errno_constants(INIT_FUNC_ARGS_PASSTHRU); php_add_tick_function(pcntl_signal_dispatch, NULL); + orig_interrupt_function = zend_interrupt_function; + zend_interrupt_function = pcntl_interrupt_function; return SUCCESS; } @@ -1317,6 +1328,9 @@ static void pcntl_signal_handler(int signo) } PCNTL_G(tail) = psig; PCNTL_G(pending_signals) = 1; + if (PCNTL_G(async_signals)) { + EG(vm_interrupt) = 1; + } } void pcntl_signal_dispatch() @@ -1375,7 +1389,30 @@ void pcntl_signal_dispatch() sigprocmask(SIG_SETMASK, &old_mask, NULL); } +/* {{{ proto bool pcntl_async_signals([bool on[) + Enable/disable asynchronous signal handling and return the old setting. */ +PHP_FUNCTION(pcntl_async_signals) +{ + zend_bool on; + if (ZEND_NUM_ARGS() == 0) { + RETURN_BOOL(PCNTL_G(async_signals)); + } + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &on) == FAILURE) { + return; + } + RETVAL_BOOL(PCNTL_G(async_signals)); + PCNTL_G(async_signals) = on; +} +/* }}} */ + +static void pcntl_interrupt_function(zend_execute_data *execute_data) +{ + pcntl_signal_dispatch(); + if (orig_interrupt_function) { + orig_interrupt_function(execute_data); + } +} /* * Local variables: diff --git a/ext/pcntl/php_pcntl.h b/ext/pcntl/php_pcntl.h index 20e7b2964a2..816bffb480f 100644 --- a/ext/pcntl/php_pcntl.h +++ b/ext/pcntl/php_pcntl.h @@ -68,6 +68,7 @@ PHP_FUNCTION(pcntl_getpriority); #ifdef HAVE_SETPRIORITY PHP_FUNCTION(pcntl_setpriority); #endif +PHP_FUNCTION(pcntl_async_signals); struct php_pcntl_pending_signal { struct php_pcntl_pending_signal *next; @@ -80,6 +81,7 @@ ZEND_BEGIN_MODULE_GLOBALS(pcntl) struct php_pcntl_pending_signal *head, *tail, *spares; int last_error; volatile char pending_signals; + zend_bool async_signals; ZEND_END_MODULE_GLOBALS(pcntl) #ifdef ZTS diff --git a/ext/pcntl/tests/async_signals.phpt b/ext/pcntl/tests/async_signals.phpt new file mode 100644 index 00000000000..b650606df30 --- /dev/null +++ b/ext/pcntl/tests/async_signals.phpt @@ -0,0 +1,25 @@ +--TEST-- +Asynchronous signal handling through VM interrupts +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Start! +Signal handler called! +Done!