/src/php-src/Zend/zend_fibers.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | +----------------------------------------------------------------------+ |
3 | | | Zend Engine | |
4 | | +----------------------------------------------------------------------+ |
5 | | | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | |
6 | | +----------------------------------------------------------------------+ |
7 | | | This source file is subject to version 2.00 of the Zend license, | |
8 | | | that is bundled with this package in the file LICENSE, and is | |
9 | | | available through the world-wide-web at the following url: | |
10 | | | http://www.zend.com/license/2_00.txt. | |
11 | | | If you did not receive a copy of the Zend license and are unable to | |
12 | | | obtain it through the world-wide-web, please send a note to | |
13 | | | license@zend.com so we can mail you a copy immediately. | |
14 | | +----------------------------------------------------------------------+ |
15 | | | Authors: Aaron Piotrowski <aaron@trowski.com> | |
16 | | | Martin Schröder <m.schroeder2007@gmail.com> | |
17 | | +----------------------------------------------------------------------+ |
18 | | */ |
19 | | |
20 | | #ifndef ZEND_FIBERS_H |
21 | | #define ZEND_FIBERS_H |
22 | | |
23 | | #include "zend_API.h" |
24 | | #include "zend_types.h" |
25 | | |
26 | 4.33k | #define ZEND_FIBER_GUARD_PAGES 1 |
27 | | |
28 | 33 | #define ZEND_FIBER_DEFAULT_C_STACK_SIZE (4096 * (((sizeof(void *)) < 8) ? 256 : 512)) |
29 | 1.44k | #define ZEND_FIBER_VM_STACK_SIZE (1024 * sizeof(zval)) |
30 | | |
31 | | BEGIN_EXTERN_C() |
32 | | |
33 | | typedef enum { |
34 | | ZEND_FIBER_STATUS_INIT, |
35 | | ZEND_FIBER_STATUS_RUNNING, |
36 | | ZEND_FIBER_STATUS_SUSPENDED, |
37 | | ZEND_FIBER_STATUS_DEAD, |
38 | | } zend_fiber_status; |
39 | | |
40 | | typedef enum { |
41 | | ZEND_FIBER_FLAG_THREW = 1 << 0, |
42 | | ZEND_FIBER_FLAG_BAILOUT = 1 << 1, |
43 | | ZEND_FIBER_FLAG_DESTROYED = 1 << 2, |
44 | | } zend_fiber_flag; |
45 | | |
46 | | typedef enum { |
47 | | ZEND_FIBER_TRANSFER_FLAG_ERROR = 1 << 0, |
48 | | ZEND_FIBER_TRANSFER_FLAG_BAILOUT = 1 << 1 |
49 | | } zend_fiber_transfer_flag; |
50 | | |
51 | | void zend_register_fiber_ce(void); |
52 | | void zend_fiber_init(void); |
53 | | void zend_fiber_shutdown(void); |
54 | | |
55 | | extern ZEND_API zend_class_entry *zend_ce_fiber; |
56 | | |
57 | | typedef struct _zend_fiber_stack zend_fiber_stack; |
58 | | |
59 | | /* Encapsulates data needed for a context switch. */ |
60 | | typedef struct _zend_fiber_transfer { |
61 | | /* Fiber that will be switched to / has resumed us. */ |
62 | | zend_fiber_context *context; |
63 | | |
64 | | /* Value to that should be send to (or was received from) a fiber. */ |
65 | | zval value; |
66 | | |
67 | | /* Bitmask of flags defined in enum zend_fiber_transfer_flag. */ |
68 | | uint8_t flags; |
69 | | } zend_fiber_transfer; |
70 | | |
71 | | /* Coroutine functions must populate the given transfer with a new context |
72 | | * and (optional) data before they return. */ |
73 | | typedef void (*zend_fiber_coroutine)(zend_fiber_transfer *transfer); |
74 | | typedef void (*zend_fiber_clean)(zend_fiber_context *context); |
75 | | |
76 | | struct _zend_fiber_context { |
77 | | /* Pointer to boost.context or ucontext_t data. */ |
78 | | void *handle; |
79 | | |
80 | | /* Pointer that identifies the fiber type. */ |
81 | | void *kind; |
82 | | |
83 | | /* Entrypoint function of the fiber. */ |
84 | | zend_fiber_coroutine function; |
85 | | |
86 | | /* Cleanup function for fiber. */ |
87 | | zend_fiber_clean cleanup; |
88 | | |
89 | | /* Assigned C stack. */ |
90 | | zend_fiber_stack *stack; |
91 | | |
92 | | /* Fiber status. */ |
93 | | zend_fiber_status status; |
94 | | |
95 | | /* Observer state */ |
96 | | zend_execute_data *top_observed_frame; |
97 | | |
98 | | /* Reserved for extensions */ |
99 | | void *reserved[ZEND_MAX_RESERVED_RESOURCES]; |
100 | | }; |
101 | | |
102 | | struct _zend_fiber { |
103 | | /* PHP object handle. */ |
104 | | zend_object std; |
105 | | |
106 | | /* Flags are defined in enum zend_fiber_flag. */ |
107 | | uint8_t flags; |
108 | | |
109 | | /* Native C fiber context. */ |
110 | | zend_fiber_context context; |
111 | | |
112 | | /* Fiber that resumed us. */ |
113 | | zend_fiber_context *caller; |
114 | | |
115 | | /* Fiber that suspended us. */ |
116 | | zend_fiber_context *previous; |
117 | | |
118 | | /* Callback and info / cache to be used when fiber is started. */ |
119 | | zend_fcall_info fci; |
120 | | zend_fcall_info_cache fci_cache; |
121 | | |
122 | | /* Current Zend VM execute data being run by the fiber. */ |
123 | | zend_execute_data *execute_data; |
124 | | |
125 | | /* Frame on the bottom of the fiber vm stack. */ |
126 | | zend_execute_data *stack_bottom; |
127 | | |
128 | | /* Active fiber vm stack. */ |
129 | | zend_vm_stack vm_stack; |
130 | | |
131 | | /* Storage for fiber return value. */ |
132 | | zval result; |
133 | | }; |
134 | | |
135 | | ZEND_API zend_result zend_fiber_start(zend_fiber *fiber, zval *return_value); |
136 | | ZEND_API void zend_fiber_resume(zend_fiber *fiber, zval *value, zval *return_value); |
137 | | ZEND_API void zend_fiber_suspend(zend_fiber *fiber, zval *value, zval *return_value); |
138 | | |
139 | | /* These functions may be used to create custom fiber objects using the bundled fiber switching context. */ |
140 | | ZEND_API zend_result zend_fiber_init_context(zend_fiber_context *context, void *kind, zend_fiber_coroutine coroutine, size_t stack_size); |
141 | | ZEND_API void zend_fiber_destroy_context(zend_fiber_context *context); |
142 | | ZEND_API void zend_fiber_switch_context(zend_fiber_transfer *transfer); |
143 | | #ifdef ZEND_CHECK_STACK_LIMIT |
144 | | ZEND_API void* zend_fiber_stack_limit(zend_fiber_stack *stack); |
145 | | ZEND_API void* zend_fiber_stack_base(zend_fiber_stack *stack); |
146 | | #endif /* ZEND_CHECK_STACK_LIMIT */ |
147 | | |
148 | | ZEND_API void zend_fiber_switch_block(void); |
149 | | ZEND_API void zend_fiber_switch_unblock(void); |
150 | | ZEND_API bool zend_fiber_switch_blocked(void); |
151 | | |
152 | | END_EXTERN_C() |
153 | | |
154 | | static zend_always_inline zend_fiber *zend_fiber_from_context(zend_fiber_context *context) |
155 | 718 | { |
156 | 718 | ZEND_ASSERT(context->kind == zend_ce_fiber && "Fiber context does not belong to a Zend fiber"); |
157 | | |
158 | 718 | return (zend_fiber *)(((char *) context) - XtOffsetOf(zend_fiber, context)); |
159 | 718 | } Unexecuted instantiation: php_reflection.c:zend_fiber_from_context Unexecuted instantiation: main.c:zend_fiber_from_context Unexecuted instantiation: compact_vars.c:zend_fiber_from_context Unexecuted instantiation: optimize_temp_vars_5.c:zend_fiber_from_context Unexecuted instantiation: zend_API.c:zend_fiber_from_context Unexecuted instantiation: zend_compile.c:zend_fiber_from_context Unexecuted instantiation: zend_default_classes.c:zend_fiber_from_context Unexecuted instantiation: zend_enum.c:zend_fiber_from_context Unexecuted instantiation: zend_exceptions.c:zend_fiber_from_context Unexecuted instantiation: zend_execute_API.c:zend_fiber_from_context Unexecuted instantiation: zend_execute.c:zend_fiber_from_context zend_fibers.c:zend_fiber_from_context Line | Count | Source | 155 | 718 | { | 156 | 718 | ZEND_ASSERT(context->kind == zend_ce_fiber && "Fiber context does not belong to a Zend fiber"); | 157 | | | 158 | 718 | return (zend_fiber *)(((char *) context) - XtOffsetOf(zend_fiber, context)); | 159 | 718 | } |
Unexecuted instantiation: zend_gc.c:zend_fiber_from_context Unexecuted instantiation: zend_generators.c:zend_fiber_from_context Unexecuted instantiation: zend_inheritance.c:zend_fiber_from_context Unexecuted instantiation: zend_object_handlers.c:zend_fiber_from_context Unexecuted instantiation: zend_objects_API.c:zend_fiber_from_context Unexecuted instantiation: zend_observer.c:zend_fiber_from_context Unexecuted instantiation: zend_opcode.c:zend_fiber_from_context Unexecuted instantiation: zend.c:zend_fiber_from_context |
160 | | |
161 | | static zend_always_inline zend_fiber_context *zend_fiber_get_context(zend_fiber *fiber) |
162 | 0 | { |
163 | 0 | return &fiber->context; |
164 | 0 | } Unexecuted instantiation: php_reflection.c:zend_fiber_get_context Unexecuted instantiation: main.c:zend_fiber_get_context Unexecuted instantiation: compact_vars.c:zend_fiber_get_context Unexecuted instantiation: optimize_temp_vars_5.c:zend_fiber_get_context Unexecuted instantiation: zend_API.c:zend_fiber_get_context Unexecuted instantiation: zend_compile.c:zend_fiber_get_context Unexecuted instantiation: zend_default_classes.c:zend_fiber_get_context Unexecuted instantiation: zend_enum.c:zend_fiber_get_context Unexecuted instantiation: zend_exceptions.c:zend_fiber_get_context Unexecuted instantiation: zend_execute_API.c:zend_fiber_get_context Unexecuted instantiation: zend_execute.c:zend_fiber_get_context Unexecuted instantiation: zend_fibers.c:zend_fiber_get_context Unexecuted instantiation: zend_gc.c:zend_fiber_get_context Unexecuted instantiation: zend_generators.c:zend_fiber_get_context Unexecuted instantiation: zend_inheritance.c:zend_fiber_get_context Unexecuted instantiation: zend_object_handlers.c:zend_fiber_get_context Unexecuted instantiation: zend_objects_API.c:zend_fiber_get_context Unexecuted instantiation: zend_observer.c:zend_fiber_get_context Unexecuted instantiation: zend_opcode.c:zend_fiber_get_context Unexecuted instantiation: zend.c:zend_fiber_get_context |
165 | | |
166 | | #endif |