@@ -88,6 +88,8 @@ SW_EXTERN_C_BEGIN
88
88
static PHP_METHOD (swoole_coroutine, exists);
89
89
static PHP_METHOD (swoole_coroutine, yield);
90
90
static PHP_METHOD (swoole_coroutine, resume);
91
+ static PHP_METHOD (swoole_coroutine, cancel);
92
+ static PHP_METHOD (swoole_coroutine, isCanceled);
91
93
static PHP_METHOD (swoole_coroutine, stats);
92
94
static PHP_METHOD (swoole_coroutine, getCid);
93
95
static PHP_METHOD (swoole_coroutine, getPcid);
@@ -113,6 +115,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_create, 0, 0, 1)
113
115
ZEND_ARG_VARIADIC_INFO(0 , params)
114
116
ZEND_END_ARG_INFO()
115
117
118
+ ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_cancel, 0 , 0 , 1 )
119
+ ZEND_ARG_INFO(0 , cid)
120
+ ZEND_END_ARG_INFO()
121
+
116
122
ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_resume, 0 , 0 , 1 )
117
123
ZEND_ARG_INFO(0 , cid)
118
124
ZEND_END_ARG_INFO()
@@ -160,6 +166,8 @@ static const zend_function_entry swoole_coroutine_methods[] =
160
166
PHP_ME (swoole_coroutine_scheduler, getOptions, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
161
167
PHP_ME (swoole_coroutine, exists, arginfo_swoole_coroutine_exists, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
162
168
PHP_ME (swoole_coroutine, yield, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
169
+ PHP_ME (swoole_coroutine, cancel, arginfo_swoole_coroutine_cancel, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
170
+ PHP_ME (swoole_coroutine, isCanceled, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
163
171
PHP_MALIAS (swoole_coroutine, suspend, yield, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
164
172
PHP_ME (swoole_coroutine, resume, arginfo_swoole_coroutine_resume, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
165
173
PHP_ME (swoole_coroutine, stats, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
@@ -352,7 +360,7 @@ void PHPCoroutine::activate() {
352
360
/* *
353
361
* deactivate when reactor free.
354
362
*/
355
- SwooleTG. reactor ->add_destroy_callback (deactivate, nullptr );
363
+ sw_reactor () ->add_destroy_callback (deactivate, nullptr );
356
364
Coroutine::activate ();
357
365
activated = true ;
358
366
}
@@ -954,9 +962,9 @@ PHP_FUNCTION(swoole_coroutine_defer) {
954
962
PHPCoroutine::defer (defer_fci);
955
963
}
956
964
957
- PHP_METHOD (swoole_coroutine, stats) {
965
+ static PHP_METHOD (swoole_coroutine, stats) {
958
966
array_init (return_value);
959
- add_assoc_long_ex (return_value, ZEND_STRL (" event_num" ), SwooleTG. reactor ? SwooleTG. reactor ->event_num : 0 );
967
+ add_assoc_long_ex (return_value, ZEND_STRL (" event_num" ), sw_reactor () ? sw_reactor () ->event_num : 0 );
960
968
add_assoc_long_ex (
961
969
return_value, ZEND_STRL (" signal_listener_num" ), SwooleTG.signal_listener_num + SwooleTG.co_signal_listener_num );
962
970
@@ -994,7 +1002,7 @@ PHP_METHOD(swoole_coroutine, getPcid) {
994
1002
RETURN_LONG (ret);
995
1003
}
996
1004
997
- PHP_METHOD (swoole_coroutine, getContext) {
1005
+ static PHP_METHOD (swoole_coroutine, getContext) {
998
1006
zend_long cid = 0 ;
999
1007
1000
1008
ZEND_PARSE_PARAMETERS_START (0 , 1 )
@@ -1005,6 +1013,7 @@ PHP_METHOD(swoole_coroutine, getContext) {
1005
1013
PHPContext *task =
1006
1014
(PHPContext *) (EXPECTED (cid == 0 ) ? Coroutine::get_current_task () : Coroutine::get_task_by_cid (cid));
1007
1015
if (UNEXPECTED (!task)) {
1016
+ swoole_set_last_error (SW_ERROR_CO_NOT_EXISTS);
1008
1017
RETURN_NULL ();
1009
1018
}
1010
1019
if (UNEXPECTED (task->context == (zend_object *) ~0 )) {
@@ -1020,7 +1029,7 @@ PHP_METHOD(swoole_coroutine, getContext) {
1020
1029
RETURN_OBJ (task->context );
1021
1030
}
1022
1031
1023
- PHP_METHOD (swoole_coroutine, getElapsed) {
1032
+ static PHP_METHOD (swoole_coroutine, getElapsed) {
1024
1033
zend_long cid = 0 ;
1025
1034
zend_long ret;
1026
1035
@@ -1033,7 +1042,7 @@ PHP_METHOD(swoole_coroutine, getElapsed) {
1033
1042
RETURN_LONG (ret);
1034
1043
}
1035
1044
1036
- PHP_METHOD (swoole_coroutine, exists) {
1045
+ static PHP_METHOD (swoole_coroutine, exists) {
1037
1046
zend_long cid;
1038
1047
1039
1048
ZEND_PARSE_PARAMETERS_START (1 , 1 )
@@ -1043,7 +1052,7 @@ PHP_METHOD(swoole_coroutine, exists) {
1043
1052
RETURN_BOOL (Coroutine::get_by_cid (cid) != nullptr );
1044
1053
}
1045
1054
1046
- PHP_METHOD (swoole_coroutine, resume) {
1055
+ static PHP_METHOD (swoole_coroutine, resume) {
1047
1056
long cid;
1048
1057
if (zend_parse_parameters (ZEND_NUM_ARGS (), " l" , &cid) == FAILURE) {
1049
1058
RETURN_FALSE;
@@ -1058,16 +1067,47 @@ PHP_METHOD(swoole_coroutine, resume) {
1058
1067
Coroutine *co = coroutine_iterator->second ;
1059
1068
user_yield_coros.erase (cid);
1060
1069
co->resume ();
1070
+
1061
1071
RETURN_TRUE;
1062
1072
}
1063
1073
1064
- PHP_METHOD (swoole_coroutine, yield) {
1074
+ static PHP_METHOD (swoole_coroutine, yield) {
1065
1075
Coroutine *co = Coroutine::get_current_safe ();
1066
1076
user_yield_coros[co->get_cid ()] = co;
1067
- co->yield ();
1077
+
1078
+ Coroutine::CancelFunc cancel_fn = [](Coroutine *co){
1079
+ user_yield_coros.erase (co->get_cid ());
1080
+ co->resume ();
1081
+ return true ;
1082
+ };
1083
+ co->yield (&cancel_fn);
1084
+ if (co->is_canceled ()) {
1085
+ swoole_set_last_error (SW_ERROR_CO_CANCELED);
1086
+ RETURN_FALSE;
1087
+ }
1088
+
1068
1089
RETURN_TRUE;
1069
1090
}
1070
1091
1092
+ static PHP_METHOD (swoole_coroutine, cancel) {
1093
+ long cid;
1094
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), " l" , &cid) == FAILURE) {
1095
+ RETURN_FALSE;
1096
+ }
1097
+
1098
+ Coroutine *co = swoole_coroutine_get (cid);
1099
+ if (!co) {
1100
+ swoole_set_last_error (SW_ERROR_CO_NOT_EXISTS);
1101
+ RETURN_FALSE;
1102
+ }
1103
+ RETURN_BOOL (co->cancel ());
1104
+ }
1105
+
1106
+ static PHP_METHOD (swoole_coroutine, isCanceled) {
1107
+ Coroutine *co = Coroutine::get_current_safe ();
1108
+ RETURN_BOOL (co->is_canceled ());
1109
+ }
1110
+
1071
1111
PHP_FUNCTION (swoole_test_kernel_coroutine) {
1072
1112
if (!PHPCoroutine::is_activated ()) {
1073
1113
RETURN_FALSE;
@@ -1089,7 +1129,7 @@ PHP_FUNCTION(swoole_test_kernel_coroutine) {
1089
1129
});
1090
1130
}
1091
1131
1092
- PHP_METHOD (swoole_coroutine, getBackTrace) {
1132
+ static PHP_METHOD (swoole_coroutine, getBackTrace) {
1093
1133
zend_long cid = 0 ;
1094
1134
zend_long options = DEBUG_BACKTRACE_PROVIDE_OBJECT;
1095
1135
zend_long limit = 0 ;
@@ -1106,6 +1146,7 @@ PHP_METHOD(swoole_coroutine, getBackTrace) {
1106
1146
} else {
1107
1147
PHPContext *task = (PHPContext *) PHPCoroutine::get_context_by_cid (cid);
1108
1148
if (UNEXPECTED (!task)) {
1149
+ swoole_set_last_error (SW_ERROR_CO_NOT_EXISTS);
1109
1150
RETURN_FALSE;
1110
1151
}
1111
1152
zend_execute_data *ex_backup = EG (current_execute_data);
@@ -1115,7 +1156,7 @@ PHP_METHOD(swoole_coroutine, getBackTrace) {
1115
1156
}
1116
1157
}
1117
1158
1118
- PHP_METHOD (swoole_coroutine, printBackTrace) {
1159
+ static PHP_METHOD (swoole_coroutine, printBackTrace) {
1119
1160
zend_long cid = 0 ;
1120
1161
zend_long options = DEBUG_BACKTRACE_PROVIDE_OBJECT;
1121
1162
zend_long limit = 0 ;
@@ -1136,6 +1177,7 @@ PHP_METHOD(swoole_coroutine, printBackTrace) {
1136
1177
} else {
1137
1178
PHPContext *task = (PHPContext *) PHPCoroutine::get_context_by_cid (cid);
1138
1179
if (UNEXPECTED (!task)) {
1180
+ swoole_set_last_error (SW_ERROR_CO_NOT_EXISTS);
1139
1181
RETURN_FALSE;
1140
1182
}
1141
1183
zend_execute_data *ex_backup = EG (current_execute_data);
@@ -1145,7 +1187,7 @@ PHP_METHOD(swoole_coroutine, printBackTrace) {
1145
1187
}
1146
1188
}
1147
1189
1148
- PHP_METHOD (swoole_coroutine, list) {
1190
+ static PHP_METHOD (swoole_coroutine, list) {
1149
1191
zval zlist;
1150
1192
array_init (&zlist);
1151
1193
for (auto &co : Coroutine::coroutines) {
0 commit comments