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,12 +107,15 @@ 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 }
@@ -126,21 +126,25 @@ PHP_FUNCTION(sapi_windows_set_ctrl_handler)
126126 RETURN_THROWS ();
127127 }
128128
129- if (!ZEND_FCI_INITIALIZED (fci )) {
130- zval_ptr_dtor (& ctrl_handler );
131- ZVAL_UNDEF (& ctrl_handler );
129+ if (!ZEND_FCC_INITIALIZED (fcc )) {
130+ if (ZEND_FCC_INITIALIZED (ctrl_handler )) {
131+ zend_fcc_dtor (& ctrl_handler );
132+ }
132133 RETURN_BOOL (SetConsoleCtrlHandler (NULL , add ));
133134 }
134135
135136 if (!SetConsoleCtrlHandler (NULL , FALSE) || !SetConsoleCtrlHandler (php_win32_signal_system_ctrl_handler , add )) {
136137 zend_string * func_name = zend_get_callable_name (& fci .function_name );
137138 php_error_docref (NULL , E_WARNING , "Unable to attach %s as a CTRL handler" , ZSTR_VAL (func_name ));
138139 zend_string_release_ex (func_name , 0 );
140+ zend_release_fcall_info_cache (& fcc );
139141 RETURN_FALSE ;
140142 }
141143
142- zval_ptr_dtor (& ctrl_handler );
143- ZVAL_COPY (& ctrl_handler , & fci .function_name );
144+ if (ZEND_FCC_INITIALIZED (ctrl_handler )) {
145+ zend_fcc_dtor (& ctrl_handler );
146+ }
147+ zend_fcc_dup (& ctrl_handler , & fcc );
144148
145149 RETURN_TRUE ;
146150}/*}}}*/
@@ -163,7 +167,7 @@ PHP_FUNCTION(sapi_windows_generate_ctrl_event)
163167
164168 ret = (GenerateConsoleCtrlEvent (evt , pid ) != 0 );
165169
166- if (IS_UNDEF != Z_TYPE (ctrl_handler )) {
170+ if (ZEND_FCC_INITIALIZED (ctrl_handler )) {
167171 ret = ret && SetConsoleCtrlHandler (php_win32_signal_system_ctrl_handler , TRUE);
168172 }
169173
0 commit comments