File tree Expand file tree Collapse file tree 5 files changed +209
-0
lines changed Expand file tree Collapse file tree 5 files changed +209
-0
lines changed Original file line number Diff line number Diff line change @@ -88,6 +88,9 @@ struct _zend_fiber_context {
88
88
/* Fiber status. */
89
89
zend_fiber_status status ;
90
90
91
+ /* Observer state */
92
+ zend_execute_data * top_observed_frame ;
93
+
91
94
/* Reserved for extensions */
92
95
void * reserved [ZEND_MAX_RESERVED_RESOURCES ];
93
96
};
Original file line number Diff line number Diff line change @@ -321,6 +321,8 @@ ZEND_API void ZEND_FASTCALL zend_observer_fiber_init_notify(zend_fiber_context *
321
321
zend_llist_element * element ;
322
322
zend_observer_fiber_init_handler callback ;
323
323
324
+ initializing -> top_observed_frame = NULL ;
325
+
324
326
for (element = zend_observer_fiber_init .head ; element ; element = element -> next ) {
325
327
callback = * (zend_observer_fiber_init_handler * ) element -> data ;
326
328
callback (initializing );
@@ -332,10 +334,17 @@ ZEND_API void ZEND_FASTCALL zend_observer_fiber_switch_notify(zend_fiber_context
332
334
zend_llist_element * element ;
333
335
zend_observer_fiber_switch_handler callback ;
334
336
337
+ if (EG (current_execute_data ) == NULL ) {
338
+ zend_observer_fcall_end_all (); // fiber is either finished (call will do nothing) or has bailed out
339
+ }
340
+
335
341
for (element = zend_observer_fiber_switch .head ; element ; element = element -> next ) {
336
342
callback = * (zend_observer_fiber_switch_handler * ) element -> data ;
337
343
callback (from , to );
338
344
}
345
+
346
+ from -> top_observed_frame = current_observed_frame ;
347
+ current_observed_frame = to -> top_observed_frame ;
339
348
}
340
349
341
350
ZEND_API void ZEND_FASTCALL zend_observer_fiber_destroy_notify (zend_fiber_context * destroying )
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ Observer: Basic function observing in fibers
3
+ --EXTENSIONS--
4
+ zend_test
5
+ --INI--
6
+ zend_test.observer.enabled=1
7
+ zend_test.observer.observe_all=1
8
+ zend_test.observer.fiber_init=1
9
+ zend_test.observer.fiber_switch=1
10
+ zend_test.observer.fiber_destroy=1
11
+ --FILE--
12
+ <?php
13
+
14
+ $ fiber = new Fiber (function (): void {
15
+ var_dump (1 );
16
+ Fiber::suspend ();
17
+ var_dump (2 );
18
+ });
19
+
20
+ $ fiber ->start ();
21
+ $ fiber ->resume ();
22
+
23
+ ?>
24
+ --EXPECTF--
25
+ <!-- init '%s' -->
26
+ <file '%s'>
27
+ <!-- init Fiber::__construct() -->
28
+ <Fiber::__construct>
29
+ </Fiber::__construct>
30
+ <!-- init Fiber::start() -->
31
+ <Fiber::start>
32
+ <!-- alloc: %s -->
33
+ <!-- switching from fiber %s to %s -->
34
+ <init '%s'>
35
+ <!-- init {closure}() -->
36
+ <{closure}>
37
+ <!-- init var_dump() -->
38
+ <var_dump>
39
+ int(1)
40
+ </var_dump>
41
+ <!-- init Fiber::suspend() -->
42
+ <Fiber::suspend>
43
+ <!-- switching from fiber %s to %s -->
44
+ <suspend '%s'>
45
+ </Fiber::start>
46
+ <!-- init Fiber::resume() -->
47
+ <Fiber::resume>
48
+ <!-- switching from fiber %s to %s -->
49
+ <resume '%s'>
50
+ </Fiber::suspend>
51
+ <var_dump>
52
+ int(2)
53
+ </var_dump>
54
+ </{closure}>
55
+ <!-- switching from fiber %s to %s -->
56
+ <returned '%s'>
57
+ <!-- destroy: %s -->
58
+ </Fiber::resume>
59
+ </file '%s'>
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ Observer: Function observing in fibers with unfinished fiber
3
+ --EXTENSIONS--
4
+ zend_test
5
+ --INI--
6
+ zend_test.observer.enabled=1
7
+ zend_test.observer.observe_all=1
8
+ zend_test.observer.fiber_init=1
9
+ zend_test.observer.fiber_switch=1
10
+ zend_test.observer.fiber_destroy=1
11
+ --FILE--
12
+ <?php
13
+
14
+ $ fiber = new Fiber (function (): void {
15
+ var_dump (1 );
16
+ Fiber::suspend ();
17
+ var_dump (2 );
18
+ });
19
+
20
+ $ fiber ->start ();
21
+
22
+ ?>
23
+ --EXPECTF--
24
+ <!-- init '%s' -->
25
+ <file '%s'>
26
+ <!-- init Fiber::__construct() -->
27
+ <Fiber::__construct>
28
+ </Fiber::__construct>
29
+ <!-- init Fiber::start() -->
30
+ <Fiber::start>
31
+ <!-- alloc: %s -->
32
+ <!-- switching from fiber %s to %s -->
33
+ <init '%s'>
34
+ <!-- init {closure}() -->
35
+ <{closure}>
36
+ <!-- init var_dump() -->
37
+ <var_dump>
38
+ int(1)
39
+ </var_dump>
40
+ <!-- init Fiber::suspend() -->
41
+ <Fiber::suspend>
42
+ <!-- switching from fiber %s to %s -->
43
+ <suspend '%s'>
44
+ </Fiber::start>
45
+ </file '%s'>
46
+ <!-- switching from fiber %s to %s -->
47
+ <destroying '%s'>
48
+ <!-- Exception: GracefulExit -->
49
+ </Fiber::suspend>
50
+ <!-- Exception: GracefulExit -->
51
+ </{closure}>
52
+ <!-- switching from fiber %s to %s -->
53
+ <destroyed '%s'>
54
+ <!-- destroy: %s -->
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ Observer: Function observing in fibers with bailout in fiber
3
+ --EXTENSIONS--
4
+ zend_test
5
+ --INI--
6
+ zend_test.observer.enabled=1
7
+ zend_test.observer.observe_all=1
8
+ zend_test.observer.fiber_init=1
9
+ zend_test.observer.fiber_switch=1
10
+ zend_test.observer.fiber_destroy=1
11
+ memory_limit=100M
12
+ --FILE--
13
+ <?php
14
+
15
+ $ notBailedOutFiber = new Fiber (function (): void {
16
+ var_dump (1 );
17
+ Fiber::suspend ();
18
+ });
19
+
20
+ $ notBailedOutFiber ->start ();
21
+
22
+ $ fiber = new Fiber (function (): void {
23
+ var_dump (2 );
24
+ Fiber::suspend ();
25
+ str_repeat ('A ' , 200_000_000 );
26
+ });
27
+
28
+ $ fiber ->start ();
29
+ $ fiber ->resume ();
30
+
31
+ ?>
32
+ --EXPECTF--
33
+ <!-- init '%s' -->
34
+ <file '%s'>
35
+ <!-- init Fiber::__construct() -->
36
+ <Fiber::__construct>
37
+ </Fiber::__construct>
38
+ <!-- init Fiber::start() -->
39
+ <Fiber::start>
40
+ <!-- alloc: %s -->
41
+ <!-- switching from fiber %s to %s -->
42
+ <init '%s'>
43
+ <!-- init {closure}() -->
44
+ <{closure}>
45
+ <!-- init var_dump() -->
46
+ <var_dump>
47
+ int(1)
48
+ </var_dump>
49
+ <!-- init Fiber::suspend() -->
50
+ <Fiber::suspend>
51
+ <!-- switching from fiber %s to %s -->
52
+ <suspend '%s'>
53
+ </Fiber::start>
54
+ <Fiber::__construct>
55
+ </Fiber::__construct>
56
+ <Fiber::start>
57
+ <!-- alloc: %s -->
58
+ <!-- switching from fiber %s to %s -->
59
+ <init '%s'>
60
+ <!-- init {closure}() -->
61
+ <{closure}>
62
+ <var_dump>
63
+ int(2)
64
+ </var_dump>
65
+ <Fiber::suspend>
66
+ <!-- switching from fiber %s to %s -->
67
+ <suspend '%s'>
68
+ </Fiber::start>
69
+ <!-- init Fiber::resume() -->
70
+ <Fiber::resume>
71
+ <!-- switching from fiber %s to %s -->
72
+ <resume '%s'>
73
+ </Fiber::suspend>
74
+ <!-- init str_repeat() -->
75
+ <str_repeat>
76
+
77
+ Fatal error: Allowed memory size of 104857600 bytes exhausted %s on line %d
78
+ </str_repeat>
79
+ </{closure}>
80
+ <!-- switching from fiber %s to %s -->
81
+ <returned '%s'>
82
+ <!-- destroy: %s -->
83
+ </Fiber::resume>
84
+ </file '%s'>
You can’t perform that action at this time.
0 commit comments