-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathphp_eventloop.h
More file actions
189 lines (155 loc) · 4.5 KB
/
php_eventloop.h
File metadata and controls
189 lines (155 loc) · 4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
* Copyright (c) 2026 Aleksandr Cherednikov
* Licensed under the MIT License. See LICENSE for details.
*/
#ifndef PHP_EVENTLOOP_H
# define PHP_EVENTLOOP_H
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "php.h"
# include "php_network.h"
# ifdef HAVE_FIBERS
# include "zend_fibers.h"
# endif
# define PHP_EVENTLOOP_VERSION "1.0.0"
extern zend_module_entry eventloop_module_entry;
# define phpext_eventloop_ptr &eventloop_module_entry
/* Forward declarations */
typedef struct _eventloop_callback eventloop_callback;
typedef struct _eventloop_timer_heap eventloop_timer_heap;
/* {{{ I/O driver interface */
typedef struct _eventloop_driver {
const char *name;
int (*init)(void);
void (*shutdown)(void);
int (*add)(eventloop_callback *cb);
void (*remove)(eventloop_callback *cb);
int (*poll)(double timeout);
} eventloop_driver;
/* }}} */
/* {{{ Callback types */
typedef enum {
EVENTLOOP_CB_DEFER = 0,
EVENTLOOP_CB_DELAY = 1,
EVENTLOOP_CB_REPEAT = 2,
EVENTLOOP_CB_READABLE = 3,
EVENTLOOP_CB_WRITABLE = 4,
EVENTLOOP_CB_SIGNAL = 5,
} eventloop_cb_type;
# define EVENTLOOP_CB_FLAG_ENABLED (1 << 0)
# define EVENTLOOP_CB_FLAG_REFERENCED (1 << 1)
# define EVENTLOOP_CB_FLAG_CANCELLED (1 << 2)
/* }}} */
/* {{{ Callback structure */
struct _eventloop_callback {
zend_string *id;
eventloop_cb_type type;
uint8_t flags;
zval closure;
union {
struct {
/* no extra data */
} defer;
struct {
double delay;
double expiry;
} delay;
struct {
double interval;
double expiry;
} repeat;
struct {
zval stream;
php_socket_t fd;
} io;
struct {
int signo;
} signal;
};
uint32_t heap_index; /* Position in timer heap (for delay/repeat) */
};
/* }}} */
/* {{{ Timer min-heap */
struct _eventloop_timer_heap {
eventloop_callback **data;
uint32_t size;
uint32_t capacity;
};
/* }}} */
/* {{{ Microtask entry */
typedef struct _eventloop_microtask {
zval closure;
zval args;
} eventloop_microtask;
/* }}} */
/* {{{ Module globals */
ZEND_BEGIN_MODULE_GLOBALS(eventloop)
HashTable callbacks;
zend_string **deferred_queue;
uint32_t deferred_count;
uint32_t deferred_capacity;
eventloop_microtask *microtask_queue;
uint32_t microtask_count;
uint32_t microtask_capacity;
eventloop_timer_heap timer_heap;
HashTable signal_callbacks;
eventloop_driver *driver;
uint64_t next_id;
uint32_t io_watcher_count;
bool running;
bool stopped;
zval error_handler;
ZEND_END_MODULE_GLOBALS(eventloop)
ZEND_EXTERN_MODULE_GLOBALS(eventloop)
# define EVENTLOOP_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(eventloop, v)
# if defined(ZTS) && defined(COMPILE_DL_EVENTLOOP)
ZEND_TSRMLS_CACHE_EXTERN()
# endif
/* }}} */
extern zend_class_entry *eventloop_ce;
extern zend_class_entry *eventloop_callback_type_ce;
extern zend_class_entry *eventloop_invalid_callback_error_ce;
# ifdef HAVE_FIBERS
extern zend_class_entry *eventloop_suspension_ce;
# endif
/* Time utility */
double eventloop_now(void);
/* Callback management */
eventloop_callback *eventloop_cb_create(eventloop_cb_type type, zval *closure);
void eventloop_cb_free(eventloop_callback *cb);
eventloop_callback *eventloop_cb_find(const zend_string *id);
void eventloop_cb_enable(eventloop_callback *cb);
void eventloop_cb_disable(eventloop_callback *cb);
void eventloop_cb_cancel(eventloop_callback *cb);
bool eventloop_has_referenced_callbacks(void);
/* Timer heap */
void eventloop_timer_heap_init(eventloop_timer_heap *heap);
void eventloop_timer_heap_destroy(eventloop_timer_heap *heap);
void eventloop_timer_heap_push(eventloop_timer_heap *heap, eventloop_callback *cb);
eventloop_callback *eventloop_timer_heap_peek(const eventloop_timer_heap *heap);
eventloop_callback *eventloop_timer_heap_pop(eventloop_timer_heap *heap);
void eventloop_timer_heap_remove(eventloop_timer_heap *heap, eventloop_callback *cb);
void eventloop_timer_heap_update(eventloop_timer_heap *heap, eventloop_callback *cb);
# ifdef HAVE_FIBERS
/* Suspension */
void eventloop_suspension_init(void);
# endif
/* Drivers */
eventloop_driver *eventloop_driver_select_get(void);
# ifdef HAVE_POLL
eventloop_driver *eventloop_driver_poll_get(void);
# endif
# ifdef HAVE_EPOLL
eventloop_driver *eventloop_driver_epoll_get(void);
# endif
# ifdef HAVE_KQUEUE
eventloop_driver *eventloop_driver_kqueue_get(void);
# endif
eventloop_driver *eventloop_select_best_driver(void);
/* Internal */
void eventloop_dispatch_callback(eventloop_callback *cb);
void eventloop_process_microtasks(void);
void eventloop_process_deferred(void);
void eventloop_process_timers(void);
#endif /* PHP_EVENTLOOP_H */