11<?php
22
3- class ServerException extends Exception {}
4-
5- function may_throw (bool $ cond , string $ msg ) {
6- if ($ cond ) {
7- throw new Exception ($ msg );
8- }
9- }
10-
11- /** @kphp-required */
12- function shutdown_simple () {
13- fprintf (STDERR , "execute simple shutdown \n" );
14- }
15-
16- /** @kphp-required */
17- function shutdown_exception_warning () {
18- $ msg = "running shutdown handler " ;
19- try {
20- // make KPHP generate exception-aware call that will check the
21- // CurException variable; it should be empty even if it had some
22- // exceptions before shutdown functions were executed
23- may_throw (false , "exception from shutdown handler " );
24- } catch (Throwable $ e ) {
25- $ msg = "unexpected exception in shutdown handler " ;
26- }
27- fprintf (STDERR , $ msg . "\n" );
28- }
29-
30- /** @kphp-required */
31- function shutdown_after_long_work () {
32- // unless the timer resets to 0 before this function is executed, it will not
33- // manage to finish successfully
34- do_sleep (0.75 );
35- fprintf (STDERR , "shutdown function managed to finish \n" );
36- }
37-
38- /** @kphp-required */
39- function shutdown_endless_loop () {
40- while (true ) {}
41- }
42-
43- /** @kphp-required */
44- function shutdown_with_exit1 () {
45- fprintf (STDERR , "running shutdown handler 1 \n" );
46- exit (0 );
47- }
48-
49- /** @kphp-required */
50- function shutdown_with_exit2 () {
51- fprintf (STDERR , "running shutdown handler 2 \n" );
52- }
53-
54- /** @kphp-required */
55- function shutdown_critical_error () {
56- fprintf (STDERR , "running shutdown handler critical errors \n" );
57- critical_error ("critical error from shutdown function " );
58- }
593
604/** @kphp-required */
615function shutdown_fork_wait () {
62- fprintf ( STDERR , "shutdown_fork_wait(): running_fork_id=%d \n" , (int )get_running_fork_id ());
63- fprintf ( STDERR , "before fork \n" );
6+ warning ( "shutdown_fork_wait(): running_fork_id= " . (int )get_running_fork_id () . "\n" );
7+ warning ( "before fork \n" );
648 $ resp_future = fork (forked_func (42 ));
65- fprintf ( STDERR , "after fork \n" );
9+ warning ( "after fork \n" );
6610 while (!wait_concurrently ($ resp_future )) {}
67- fprintf (STDERR , "after wait \n" );
68- }
69-
70- /** @kphp-required */
71- function shutdown_send_rpc () {
72- fprintf (STDERR , "try send rpc from shutdown \n" );
73- rpc_flush ();
11+ warning ("after wait \n" );
7412}
7513
7614function forked_func (int $ i , float $ duration = 0.5 ): int {
77- fprintf ( STDERR , "before yield \n" );
15+ warning ( "before yield \n" );
7816 sched_yield_sleep ($ duration ); // wait net
79- fprintf ( STDERR , "after yield \n" );
17+ warning ( "after yield \n" );
8018 return $ i ;
8119}
8220
83- function do_sleep (float $ seconds ) {
84- usleep ((int )(1000000 * $ seconds ));
85- }
86-
8721function do_register_shutdown_function (string $ fn ) {
8822 switch ($ fn ) {
89- case "shutdown_exception_warning " :
90- register_shutdown_function ("shutdown_exception_warning " );
91- break ;
92- case "shutdown_after_long_work " :
93- register_shutdown_function ("shutdown_after_long_work " );
94- break ;
95- case "shutdown_endless_loop " :
96- register_shutdown_function ("shutdown_endless_loop " );
97- break ;
98- case "shutdown_with_exit " :
99- register_shutdown_function ("shutdown_with_exit1 " );
100- register_shutdown_function ("shutdown_with_exit2 " );
101- break ;
102- case "shutdown_critical_error " :
103- register_shutdown_function ("shutdown_critical_error " );
104- break ;
10523 case "shutdown_fork_wait " :
10624 register_shutdown_function ("shutdown_fork_wait " );
10725 break ;
108- case "shutdown_simple " :
109- register_shutdown_function ("shutdown_simple " );
110- break ;
111- case "shutdown_send_rpc " :
112- register_shutdown_function ("shutdown_send_rpc " );
113- break ;
114- }
115- }
116-
117- function do_sigsegv () {
118- raise_sigsegv ();
119- }
120-
121- function do_exception (string $ message , int $ code ) {
122- throw new ServerException ($ message , $ code );
123- }
124-
125- function do_stack_overflow (int $ x ): int {
126- $ z = 10 ;
127- if ($ x ) {
128- $ y = do_stack_overflow ($ x + 1 );
129- $ z = $ y + 1 ;
130- }
131- $ z += do_stack_overflow ($ x + $ z );
132- return $ z ;
133- }
134-
135- function do_long_work (int $ duration ) {
136- $ s = time ();
137- while (time () - $ s <= $ duration ) {
138- }
139- }
140-
141- function long_resumable (int $ duration ): bool {
142- if (false ) { // make this function reachable from forks to make kphp generate resumable specific code
143- fork (long_resumable (-1 ));
144- sched_yield ();
14526 }
146- do_long_work ($ duration );
147- return true ;
148- }
149-
150- function send_rpc (int $ master_port , float $ duration , bool $ expect_resume = true ) {
151- $ c = new_rpc_connection ("127.0.0.1 " , $ master_port , 0 , 100 , 100 );
152- $ req_id = rpc_tl_query_one ($ c , ["_ " => "engine.sleep " , "time_ms " => (int )($ duration * 1000 )]);
153- $ succ = ($ req_id > 0 );
154- fprintf (STDERR , "RPC request sent successfully = $ succ \n" );
155- $ resp = rpc_tl_query_result_one ($ req_id );
156- if (!$ expect_resume ) {
157- critical_error ("This fork mustn't be resumed " );
158- }
159- fprintf (STDERR , "Got RPC answer = " . var_export ($ resp , true ) . "\n" );
160- return $ resp ["result " ];
16127}
16228
16329/** @kphp-immutable-class
@@ -170,71 +36,13 @@ function __construct() {
17036 }
17137}
17238
173- function capture_instance_cache_element () {
174- instance_cache_store ("test " , new InstanceCacheElement );
175- $ el = instance_cache_fetch (InstanceCacheElement::class, "test " );
176- register_shutdown_function (function () use ($ el ) {
177- // 0x7ffffff1 is a value of extra_ref_cnt_value::for_instance_cache
178- $ expected = 0x7ffffff1 ;
179- $ got = get_reference_counter ($ el ->payload );
180- if ($ got !== $ expected ) {
181- critical_error ("Reference counter of Instance Cache element mismatch: expected $ expected, got $ got " );
182- }
183- });
184- }
185-
18639function main () {
18740 foreach (json_decode (file_get_contents ('php://input ' )) as $ action ) {
188- fprintf ( STDERR , $ action ["op " ] . "\n" );
41+ warning ( $ action ["op " ] . "\n" );
18942 switch ($ action ["op " ]) {
190- case "sigsegv " :
191- do_sigsegv ();
192- break ;
193- case "exception " :
194- do_exception ((string )$ action ["msg " ], (int )$ action ["code " ]);
195- break ;
196- case "stack_overflow " :
197- do_stack_overflow (1 );
198- break ;
199- case "long_work " :
200- do_long_work ((int )$ action ["duration " ]);
201- break ;
202- case "resumable_long_work " :
203- fprintf (STDERR , "start resumable_long_work \n" );
204- long_resumable ((int )$ action ["duration " ]);
205- fprintf (STDERR , "finish resumable_long_work \n" );
206- break ;
207- case "fork_wait_resumable_long_work " :
208- $ f = fork (long_resumable ((int )$ action ["duration " ]));
209- wait ($ f );
210- break ;
211- case "sleep " :
212- do_sleep ((float )$ action ["duration " ]);
213- break ;
214- case "fork_send_rpc_without_wait " :
215- $ master_port = (int )$ action ["master_port " ];
216- $ duration = (float )$ action ["duration " ];
217- fork (send_rpc ($ master_port , $ duration , false ));
218- rpc_flush ();
219- do_sleep (0.001 );
220- rpc_flush ();
221- do_sleep (0.001 );
222- rpc_flush ();
223- break ;
224- case "send_long_rpc " :
225- $ master_port = (int )$ action ["master_port " ];
226- $ duration = (float )$ action ["duration " ];
227- send_rpc ($ master_port , $ duration );
228- break ;
229- case "critical_error " :
230- critical_error ("this code shouldn't be executed " );
231- break ;
23243 case "register_shutdown_function " :
23344 do_register_shutdown_function ((string )$ action ["msg " ]);
23445 break ;
235- case "capture_instance_cache_element " :
236- capture_instance_cache_element ();
237- break ;
23846 default :
23947 echo "unknown operation " ;
24048 return ;
0 commit comments