Skip to content

Commit 9b7519a

Browse files
committed
remove swoole_coroutine_util.cc
1 parent 913a658 commit 9b7519a

File tree

5 files changed

+259
-283
lines changed

5 files changed

+259
-283
lines changed

config.m4

-1
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,6 @@ if test "$PHP_SWOOLE" != "no"; then
517517
swoole_coroutine.cc \
518518
swoole_coroutine_scheduler.cc \
519519
swoole_coroutine_system.cc \
520-
swoole_coroutine_util.cc \
521520
swoole_event.cc \
522521
swoole_http2_client_coro.cc \
523522
swoole_http2_server.cc \

php_swoole.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ void swoole_table_init(int module_number);
312312
void swoole_timer_init(int module_number);
313313
// coroutine
314314
void swoole_async_coro_init(int module_number);
315-
void swoole_coroutine_util_init(int module_number);
315+
void swoole_coroutine_init(int module_number);
316316
void swoole_channel_coro_init(int module_number);
317317
void swoole_runtime_init(int module_number);
318318
// client

swoole.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ PHP_MINIT_FUNCTION(swoole)
609609
swoole_timer_init(module_number);
610610
// coroutine
611611
swoole_async_coro_init(module_number);
612-
swoole_coroutine_util_init(module_number);
612+
swoole_coroutine_init(module_number);
613613
swoole_channel_coro_init(module_number);
614614
swoole_runtime_init(module_number);
615615
// client

swoole_coroutine.cc

+257-2
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,109 @@
1818
*/
1919

2020
#include "php_swoole_cxx.h"
21+
#include "swoole_coroutine_scheduler.h"
22+
#include "swoole_coroutine_system.h"
2123

22-
using namespace swoole;
24+
using swoole::coroutine::System;
25+
using swoole::coroutine::Socket;
26+
using swoole::Coroutine;
27+
using swoole::PHPCoroutine;
2328

2429
#define PHP_CORO_TASK_SLOT ((int)((ZEND_MM_ALIGNED_SIZE(sizeof(php_coro_task)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval))))
2530

31+
enum sw_exit_flags
32+
{
33+
SW_EXIT_IN_COROUTINE = 1 << 1,
34+
SW_EXIT_IN_SERVER = 1 << 2
35+
};
36+
37+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_void, 0, 0, 0)
38+
ZEND_END_ARG_INFO()
39+
40+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_set, 0, 0, 1)
41+
ZEND_ARG_INFO(0, options)
42+
ZEND_END_ARG_INFO()
43+
44+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_create, 0, 0, 1)
45+
ZEND_ARG_CALLABLE_INFO(0, func, 0)
46+
ZEND_ARG_VARIADIC_INFO(0, params)
47+
ZEND_END_ARG_INFO()
48+
49+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_resume, 0, 0, 1)
50+
ZEND_ARG_INFO(0, cid)
51+
ZEND_END_ARG_INFO()
52+
53+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_exists, 0, 0, 1)
54+
ZEND_ARG_INFO(0, cid)
55+
ZEND_END_ARG_INFO()
56+
57+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_getContext, 0, 0, 0)
58+
ZEND_ARG_INFO(0, cid)
59+
ZEND_END_ARG_INFO()
60+
61+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_exec, 0, 0, 1)
62+
ZEND_ARG_INFO(0, command)
63+
ZEND_ARG_INFO(0, get_error_stream)
64+
ZEND_END_ARG_INFO()
65+
66+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_sleep, 0, 0, 1)
67+
ZEND_ARG_INFO(0, seconds)
68+
ZEND_END_ARG_INFO()
69+
70+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_fread, 0, 0, 1)
71+
ZEND_ARG_INFO(0, handle)
72+
ZEND_ARG_INFO(0, length)
73+
ZEND_END_ARG_INFO()
74+
75+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_fgets, 0, 0, 1)
76+
ZEND_ARG_INFO(0, handle)
77+
ZEND_END_ARG_INFO()
78+
79+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_fwrite, 0, 0, 2)
80+
ZEND_ARG_INFO(0, handle)
81+
ZEND_ARG_INFO(0, string)
82+
ZEND_ARG_INFO(0, length)
83+
ZEND_END_ARG_INFO()
84+
85+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_gethostbyname, 0, 0, 1)
86+
ZEND_ARG_INFO(0, domain_name)
87+
ZEND_ARG_INFO(0, family)
88+
ZEND_ARG_INFO(0, timeout)
89+
ZEND_END_ARG_INFO()
90+
91+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_defer, 0, 0, 1)
92+
ZEND_ARG_INFO(0, callback)
93+
ZEND_END_ARG_INFO()
94+
95+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_getaddrinfo, 0, 0, 1)
96+
ZEND_ARG_INFO(0, hostname)
97+
ZEND_ARG_INFO(0, family)
98+
ZEND_ARG_INFO(0, socktype)
99+
ZEND_ARG_INFO(0, protocol)
100+
ZEND_ARG_INFO(0, service)
101+
ZEND_ARG_INFO(0, timeout)
102+
ZEND_END_ARG_INFO()
103+
104+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_readFile, 0, 0, 1)
105+
ZEND_ARG_INFO(0, filename)
106+
ZEND_END_ARG_INFO()
107+
108+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_writeFile, 0, 0, 2)
109+
ZEND_ARG_INFO(0, filename)
110+
ZEND_ARG_INFO(0, data)
111+
ZEND_ARG_INFO(0, flags)
112+
ZEND_END_ARG_INFO()
113+
114+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_statvfs, 0, 0, 1)
115+
ZEND_ARG_INFO(0, path)
116+
ZEND_END_ARG_INFO()
117+
118+
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_getBackTrace, 0, 0, 0)
119+
ZEND_ARG_INFO(0, cid)
120+
ZEND_ARG_INFO(0, options)
121+
ZEND_ARG_INFO(0, limit)
122+
ZEND_END_ARG_INFO()
123+
26124
bool PHPCoroutine::active = false;
27125
uint64_t PHPCoroutine::max_num = SW_DEFAULT_MAX_CORO_NUM;
28126
php_coro_task PHPCoroutine::main_task = {0};
@@ -31,11 +129,122 @@ bool PHPCoroutine::schedule_thread_running = false;
31129

32130
static zend_bool* zend_vm_interrupt = nullptr;
33131
static pthread_t pidt;
132+
static user_opcode_handler_t ori_exit_handler = NULL;
34133

35134
static void (*orig_interrupt_function)(zend_execute_data *execute_data);
36-
37135
static void (*orig_error_function)(int type, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args);
38136

137+
static zend_class_entry *swoole_coroutine_util_ce;
138+
static zend_class_entry *swoole_exit_exception_ce;
139+
static zend_object_handlers swoole_exit_exception_handlers;
140+
141+
static const zend_function_entry swoole_coroutine_util_methods[] =
142+
{
143+
/**
144+
* Coroutine Scheduler
145+
*/
146+
ZEND_FENTRY(create, ZEND_FN(swoole_coroutine_create), arginfo_swoole_coroutine_create, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
147+
ZEND_FENTRY(defer, ZEND_FN(swoole_coroutine_defer), arginfo_swoole_coroutine_defer, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
148+
PHP_ME(swoole_coroutine_scheduler, set, arginfo_swoole_coroutine_set, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
149+
PHP_ME(swoole_coroutine_scheduler, exists, arginfo_swoole_coroutine_exists, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
150+
PHP_ME(swoole_coroutine_scheduler, yield, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
151+
PHP_MALIAS(swoole_coroutine_scheduler, suspend, yield, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
152+
PHP_ME(swoole_coroutine_scheduler, resume, arginfo_swoole_coroutine_resume, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
153+
PHP_ME(swoole_coroutine_scheduler, stats, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
154+
PHP_ME(swoole_coroutine_scheduler, getCid, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
155+
PHP_MALIAS(swoole_coroutine_scheduler, getuid, getCid, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
156+
PHP_ME(swoole_coroutine_scheduler, getPcid, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
157+
PHP_ME(swoole_coroutine_scheduler, getContext, arginfo_swoole_coroutine_getContext, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
158+
PHP_ME(swoole_coroutine_scheduler, getBackTrace, arginfo_swoole_coroutine_getBackTrace, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
159+
PHP_ME(swoole_coroutine_scheduler, list, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
160+
PHP_MALIAS(swoole_coroutine_scheduler, listCoroutines, list, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
161+
PHP_ME(swoole_coroutine_scheduler, enableScheduler, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
162+
PHP_ME(swoole_coroutine_scheduler, disableScheduler, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
163+
/**
164+
* Coroutine System API
165+
*/
166+
ZEND_FENTRY(exec, ZEND_FN(swoole_coroutine_exec), arginfo_swoole_coroutine_exec, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
167+
ZEND_FENTRY(gethostbyname, ZEND_FN(swoole_coroutine_gethostbyname), arginfo_swoole_coroutine_gethostbyname, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
168+
PHP_ME(swoole_coroutine_system, sleep, arginfo_swoole_coroutine_sleep, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
169+
PHP_ME(swoole_coroutine_system, fread, arginfo_swoole_coroutine_fread, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
170+
PHP_ME(swoole_coroutine_system, fgets, arginfo_swoole_coroutine_fgets, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
171+
PHP_ME(swoole_coroutine_system, fwrite, arginfo_swoole_coroutine_fwrite, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
172+
PHP_ME(swoole_coroutine_system, readFile, arginfo_swoole_coroutine_readFile, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
173+
PHP_ME(swoole_coroutine_system, writeFile, arginfo_swoole_coroutine_writeFile, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
174+
PHP_ME(swoole_coroutine_system, getaddrinfo, arginfo_swoole_coroutine_getaddrinfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
175+
PHP_ME(swoole_coroutine_system, statvfs, arginfo_swoole_coroutine_statvfs, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
176+
177+
PHP_FE_END
178+
};
179+
180+
/**
181+
* Exit Exception
182+
*/
183+
static PHP_METHOD(swoole_exit_exception, getFlags);
184+
static PHP_METHOD(swoole_exit_exception, getStatus);
185+
186+
static const zend_function_entry swoole_exit_exception_methods[] =
187+
{
188+
PHP_ME(swoole_exit_exception, getFlags, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC)
189+
PHP_ME(swoole_exit_exception, getStatus, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC)
190+
PHP_FE_END
191+
};
192+
193+
static int coro_exit_handler(zend_execute_data *execute_data)
194+
{
195+
zval ex;
196+
zend_object *obj;
197+
zend_long flags = 0;
198+
if (Coroutine::get_current())
199+
{
200+
flags |= SW_EXIT_IN_COROUTINE;
201+
}
202+
if (SwooleG.serv && SwooleG.serv->gs->start)
203+
{
204+
flags |= SW_EXIT_IN_SERVER;
205+
}
206+
if (flags)
207+
{
208+
const zend_op *opline = EX(opline);
209+
zval _exit_status;
210+
zval *exit_status = NULL;
211+
212+
if (opline->op1_type != IS_UNUSED)
213+
{
214+
if (opline->op1_type == IS_CONST)
215+
{
216+
// see: https://github.com/php/php-src/commit/e70618aff6f447a298605d07648f2ce9e5a284f5
217+
#ifdef EX_CONSTANT
218+
exit_status = EX_CONSTANT(opline->op1);
219+
#else
220+
exit_status = RT_CONSTANT(opline, opline->op1);
221+
#endif
222+
}
223+
else
224+
{
225+
exit_status = EX_VAR(opline->op1.var);
226+
}
227+
if (Z_ISREF_P(exit_status))
228+
{
229+
exit_status = Z_REFVAL_P(exit_status);
230+
}
231+
ZVAL_DUP(&_exit_status, exit_status);
232+
exit_status = &_exit_status;
233+
}
234+
else
235+
{
236+
exit_status = &_exit_status;
237+
ZVAL_NULL(exit_status);
238+
}
239+
obj = zend_throw_error_exception(swoole_exit_exception_ce, "swoole exit", 0, E_ERROR);
240+
ZVAL_OBJ(&ex, obj);
241+
zend_update_property_long(swoole_exit_exception_ce, &ex, ZEND_STRL("flags"), flags);
242+
Z_TRY_ADDREF_P(exit_status);
243+
zend_update_property(swoole_exit_exception_ce, &ex, ZEND_STRL("status"), exit_status);
244+
}
245+
246+
return ZEND_USER_OPCODE_DISPATCH;
247+
}
39248

40249
static void swoole_interrupt_resume(void *data)
41250
{
@@ -550,3 +759,49 @@ int PHPCoroutine::resume_m(php_coro_context *sw_current_context, zval *retval, z
550759
task->co->resume_naked();
551760
return SW_CORO_ERR_END;
552761
}
762+
763+
void swoole_coroutine_init(int module_number)
764+
{
765+
PHPCoroutine::init();
766+
767+
SW_INIT_CLASS_ENTRY_BASE(swoole_coroutine_util, "Swoole\\Coroutine", NULL, "Co", swoole_coroutine_util_methods, NULL);
768+
SW_SET_CLASS_CREATE(swoole_coroutine_util, sw_zend_create_object_deny);
769+
770+
swoole_coroutine_scheduler_init(module_number);
771+
772+
SW_REGISTER_LONG_CONSTANT("SWOOLE_DEFAULT_MAX_CORO_NUM", SW_DEFAULT_MAX_CORO_NUM);
773+
SW_REGISTER_LONG_CONSTANT("SWOOLE_CORO_MAX_NUM_LIMIT", SW_CORO_MAX_NUM_LIMIT);
774+
SW_REGISTER_LONG_CONSTANT("SWOOLE_CORO_INIT", SW_CORO_INIT);
775+
SW_REGISTER_LONG_CONSTANT("SWOOLE_CORO_WAITING", SW_CORO_WAITING);
776+
SW_REGISTER_LONG_CONSTANT("SWOOLE_CORO_RUNNING", SW_CORO_RUNNING);
777+
SW_REGISTER_LONG_CONSTANT("SWOOLE_CORO_END", SW_CORO_END);
778+
779+
//prohibit exit in coroutine
780+
SW_INIT_CLASS_ENTRY_EX(swoole_exit_exception, "Swoole\\ExitException", NULL, NULL, swoole_exit_exception_methods, swoole_exception);
781+
zend_declare_property_long(swoole_exit_exception_ce, ZEND_STRL("flags"), 0, ZEND_ACC_PRIVATE);
782+
zend_declare_property_long(swoole_exit_exception_ce, ZEND_STRL("status"), 0, ZEND_ACC_PRIVATE);
783+
784+
SW_REGISTER_LONG_CONSTANT("SWOOLE_EXIT_IN_COROUTINE", SW_EXIT_IN_COROUTINE);
785+
SW_REGISTER_LONG_CONSTANT("SWOOLE_EXIT_IN_SERVER", SW_EXIT_IN_SERVER);
786+
787+
if (SWOOLE_G(cli))
788+
{
789+
ori_exit_handler = zend_get_user_opcode_handler(ZEND_EXIT);
790+
zend_set_user_opcode_handler(ZEND_EXIT, coro_exit_handler);
791+
}
792+
}
793+
794+
void swoole_coroutine_rshutdown()
795+
{
796+
PHPCoroutine::shutdown();
797+
}
798+
799+
static PHP_METHOD(swoole_exit_exception, getFlags)
800+
{
801+
SW_RETURN_PROPERTY("flags");
802+
}
803+
804+
static PHP_METHOD(swoole_exit_exception, getStatus)
805+
{
806+
SW_RETURN_PROPERTY("status");
807+
}

0 commit comments

Comments
 (0)