xref: /ext-fiber/fiber.h (revision cfcb53a1)
1 /*
2   +--------------------------------------------------------------------+
3   | ext-fiber                                                          |
4   +--------------------------------------------------------------------+
5   | Redistribution and use in source and binary forms, with or without |
6   | modification, are permitted provided that the conditions mentioned |
7   | in the accompanying LICENSE file are met.                          |
8   +--------------------------------------------------------------------+
9   | Authors: Aaron Piotrowski <aaron@trowski.com>                      |
10   |          Martin Schröder <m.schroeder2007@gmail.com>               |
11   +--------------------------------------------------------------------+
12 */
13 
14 #ifndef FIBER_H
15 #define FIBER_H
16 
17 #include "zend.h"
18 #include "zend_globals.h"
19 #include "zend_API.h"
20 
21 BEGIN_EXTERN_C()
22 
23 void zend_register_fiber_ce(void);
24 
25 void zend_fiber_init(void);
26 void zend_fiber_shutdown(void);
27 
28 #ifdef PHP_WIN32
29 # ifdef PHP_FIBER_EXPORTS
30 #  define PHP_FIBER_API __declspec(dllexport)
31 # else
32 #  define PHP_FIBER_API __declspec(dllimport)
33 # endif
34 #elif defined(__GNUC__) && __GNUC__ >= 4
35 # define PHP_FIBER_API __attribute__ ((visibility("default")))
36 #else
37 # define PHP_FIBER_API
38 #endif
39 
40 extern PHP_FIBER_API zend_class_entry *zend_ce_fiber;
41 
42 typedef struct _zend_fiber_context zend_fiber_context;
43 
44 typedef void (*zend_fiber_coroutine)(zend_fiber_context *context);
45 
46 typedef struct _zend_fiber_stack {
47 	void *pointer;
48 	size_t size;
49 
50 #ifdef HAVE_VALGRIND
51 	int valgrind;
52 #endif
53 } zend_fiber_stack;
54 
55 typedef struct _zend_fiber_context {
56 	void *self;
57 	void *caller;
58 	zend_fiber_coroutine function;
59 	zend_fiber_stack stack;
60 } zend_fiber_context;
61 
62 #define ZEND_FIBER_DEFAULT_STACK_SIZE (ZEND_FIBER_PAGESIZE * (((sizeof(void *)) < 8) ? 512 : 2048))
63 
64 typedef struct _zend_fiber {
65 	/* Fiber PHP object handle. */
66 	zend_object std;
67 
68 	/* Status of the fiber, one of the ZEND_FIBER_STATUS_* constants. */
69 	zend_uchar status;
70 
71 	/* Callback and info / cache to be used when fiber is started. */
72 	zend_fcall_info fci;
73 	zend_fcall_info_cache fci_cache;
74 
75 	/* Context of this fiber, will be initialized during call to Fiber::start(). */
76 	zend_fiber_context context;
77 
78 	/* Current Zend VM execute data being run by the fiber. */
79 	zend_execute_data *execute_data;
80 
81 	/* Frame on the bottom of the fiber vm stack. */
82 	zend_execute_data *stack_bottom;
83 
84 	/* Exception to be thrown from Fiber::suspend(). */
85 	zval *exception;
86 
87 	/* Storage for temporaries and fiber return value. */
88 	zval value;
89 } zend_fiber;
90 
91 typedef struct _zend_fiber_reflection {
92 	/* ReflectionFiber PHP object handle. */
93 	zend_object std;
94 
95 	/* Fiber being reflected. */
96 	zend_fiber *fiber;
97 } zend_fiber_reflection;
98 
99 typedef struct _zend_fiber_error {
100 	int type;
101 	const char *filename;
102 	uint32_t lineno;
103 	zend_string *message;
104 } zend_fiber_error;
105 
106 PHP_FIBER_API zend_fiber *zend_get_current_fiber(void);
107 PHP_FIBER_API zend_bool zend_is_fiber_exit(const zend_object *exception);
108 
109 typedef void (*zend_observer_fiber_switch_handler)(zend_fiber *from, zend_fiber *to);
110 
111 PHP_FIBER_API void zend_observer_fiber_switch_register(zend_observer_fiber_switch_handler handler);
112 
113 static const zend_uchar ZEND_FIBER_STATUS_INIT = 0;
114 static const zend_uchar ZEND_FIBER_STATUS_SUSPENDED = 0x1;
115 static const zend_uchar ZEND_FIBER_STATUS_RUNNING = 0x2;
116 static const zend_uchar ZEND_FIBER_STATUS_RETURNED = 0x4;
117 static const zend_uchar ZEND_FIBER_STATUS_THREW = 0x8;
118 static const zend_uchar ZEND_FIBER_STATUS_SHUTDOWN = 0x10;
119 static const zend_uchar ZEND_FIBER_STATUS_BAILOUT = 0x20;
120 
121 static const zend_uchar ZEND_FIBER_STATUS_FINISHED = 0x2c;
122 
123 const char *zend_fiber_backend_info(void);
124 
125 PHP_FIBER_API zend_bool zend_fiber_init_context(zend_fiber_context *context, zend_fiber_coroutine coroutine, size_t stack_size);
126 PHP_FIBER_API void zend_fiber_destroy_context(zend_fiber_context *context);
127 
128 zend_bool zend_fiber_stack_allocate(zend_fiber_stack *stack, size_t size);
129 void zend_fiber_stack_free(zend_fiber_stack *stack);
130 
131 PHP_FIBER_API void zend_fiber_switch_context(zend_fiber_context *to);
132 PHP_FIBER_API void zend_fiber_suspend_context(zend_fiber_context *current);
133 
134 #define ZEND_FIBER_GUARD_PAGES 1
135 
136 #define ZEND_FIBER_DEFAULT_C_STACK_SIZE (4096 * (((sizeof(void *)) < 8) ? 256 : 512))
137 
138 #define ZEND_FIBER_VM_STACK_SIZE (1024 * sizeof(zval))
139 
140 END_EXTERN_C()
141 
142 #endif
143 
144 /*
145  * vim: sw=4 ts=4
146  * vim600: fdm=marker
147  */
148