1818#include "win32/console.h"
1919
2020/* true globals; only used from main thread and from kernel callback */
21- static zval ctrl_handler ;
21+ static zend_fcall_info_cache ctrl_handler ;
2222static DWORD ctrl_evt = (DWORD )- 1 ;
2323static zend_atomic_bool * vm_interrupt_flag = NULL ;
2424
2525static void (* orig_interrupt_function )(zend_execute_data * execute_data );
2626
2727static void php_win32_signal_ctrl_interrupt_function (zend_execute_data * execute_data )
2828{/*{{{*/
29- if (IS_UNDEF != Z_TYPE (ctrl_handler )) {
30- zval retval , params [1 ];
29+ if (ZEND_FCC_INITIALIZED (ctrl_handler )) {
30+ zval params [1 ];
3131
3232 ZVAL_LONG (& params [0 ], ctrl_evt );
3333
34- /* If the function returns, */
35- call_user_function (NULL , NULL , & ctrl_handler , & retval , 1 , params );
36- zval_ptr_dtor (& retval );
34+ zend_call_known_fcc (& ctrl_handler , NULL , 1 , params , NULL );
3735 }
3836
3937 if (orig_interrupt_function ) {
@@ -51,7 +49,7 @@ PHP_WINUTIL_API void php_win32_signal_ctrl_handler_init(void)
5149 orig_interrupt_function = zend_interrupt_function ;
5250 zend_interrupt_function = php_win32_signal_ctrl_interrupt_function ;
5351 vm_interrupt_flag = & EG (vm_interrupt );
54- ZVAL_UNDEF ( & ctrl_handler ) ;
52+ ctrl_handler = empty_fcall_info_cache ;
5553
5654 REGISTER_MAIN_LONG_CONSTANT ("PHP_WINDOWS_EVENT_CTRL_C" , CTRL_C_EVENT , CONST_PERSISTENT );
5755 REGISTER_MAIN_LONG_CONSTANT ("PHP_WINDOWS_EVENT_CTRL_BREAK" , CTRL_BREAK_EVENT , CONST_PERSISTENT );
@@ -82,9 +80,8 @@ PHP_WINUTIL_API void php_win32_signal_ctrl_handler_request_shutdown(void)
8280
8381 /* The ctrl_handler must be cleared between requests, otherwise we can crash
8482 * due to accessing a previous request's memory. */
85- if (!Z_ISUNDEF (ctrl_handler )) {
86- zval_ptr_dtor (& ctrl_handler );
87- ZVAL_UNDEF (& ctrl_handler );
83+ if (ZEND_FCC_INITIALIZED (ctrl_handler )) {
84+ zend_fcc_dtor (& ctrl_handler );
8885 }
8986}
9087
@@ -110,37 +107,47 @@ PHP_FUNCTION(sapi_windows_set_ctrl_handler)
110107
111108
112109 /* callable argument corresponds to the CTRL handler */
113- if (zend_parse_parameters (ZEND_NUM_ARGS (), "f !|b" , & fci , & fcc , & add ) == FAILURE ) {
110+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "F !|b" , & fci , & fcc , & add ) == FAILURE ) {
114111 RETURN_THROWS ();
115112 }
116113
117114#ifdef ZTS
118115 if (!tsrm_is_main_thread ()) {
116+ if (ZEND_FCC_INITIALIZED (fcc )) {
117+ zend_release_fcall_info_cache (& fcc );
118+ }
119119 zend_throw_error (NULL , "CTRL events can only be received on the main thread" );
120120 RETURN_THROWS ();
121121 }
122122#endif
123123
124124 if (!php_win32_console_is_cli_sapi ()) {
125+ if (ZEND_FCC_INITIALIZED (fcc )) {
126+ zend_release_fcall_info_cache (& fcc );
127+ }
125128 zend_throw_error (NULL , "CTRL events trapping is only supported on console" );
126129 RETURN_THROWS ();
127130 }
128131
129- if (!ZEND_FCI_INITIALIZED (fci )) {
130- zval_ptr_dtor (& ctrl_handler );
131- ZVAL_UNDEF (& ctrl_handler );
132+ if (!ZEND_FCC_INITIALIZED (fcc )) {
133+ if (ZEND_FCC_INITIALIZED (ctrl_handler )) {
134+ zend_fcc_dtor (& ctrl_handler );
135+ }
132136 RETURN_BOOL (SetConsoleCtrlHandler (NULL , add ));
133137 }
134138
135139 if (!SetConsoleCtrlHandler (NULL , FALSE) || !SetConsoleCtrlHandler (php_win32_signal_system_ctrl_handler , add )) {
136140 zend_string * func_name = zend_get_callable_name (& fci .function_name );
137141 php_error_docref (NULL , E_WARNING , "Unable to attach %s as a CTRL handler" , ZSTR_VAL (func_name ));
138142 zend_string_release_ex (func_name , 0 );
143+ zend_release_fcall_info_cache (& fcc );
139144 RETURN_FALSE ;
140145 }
141146
142- zval_ptr_dtor (& ctrl_handler );
143- ZVAL_COPY (& ctrl_handler , & fci .function_name );
147+ if (ZEND_FCC_INITIALIZED (ctrl_handler )) {
148+ zend_fcc_dtor (& ctrl_handler );
149+ }
150+ zend_fcc_dup (& ctrl_handler , & fcc );
144151
145152 RETURN_TRUE ;
146153}/*}}}*/
@@ -163,7 +170,7 @@ PHP_FUNCTION(sapi_windows_generate_ctrl_event)
163170
164171 ret = (GenerateConsoleCtrlEvent (evt , pid ) != 0 );
165172
166- if (IS_UNDEF != Z_TYPE (ctrl_handler )) {
173+ if (ZEND_FCC_INITIALIZED (ctrl_handler )) {
167174 ret = ret && SetConsoleCtrlHandler (php_win32_signal_system_ctrl_handler , TRUE);
168175 }
169176
0 commit comments