24
24
25
25
static int ngx_http_lua_uthread_spawn (lua_State * L );
26
26
static int ngx_http_lua_uthread_wait (lua_State * L );
27
+ static int ngx_http_lua_uthread_kill (lua_State * L );
27
28
28
29
29
30
void
30
31
ngx_http_lua_inject_uthread_api (ngx_log_t * log , lua_State * L )
31
32
{
32
33
/* new thread table */
33
- lua_createtable (L , 0 /* narr */ , 2 /* nrec */ );
34
+ lua_createtable (L , 0 /* narr */ , 3 /* nrec */ );
34
35
35
36
lua_pushcfunction (L , ngx_http_lua_uthread_spawn );
36
37
lua_setfield (L , -2 , "spawn" );
37
38
38
39
lua_pushcfunction (L , ngx_http_lua_uthread_wait );
39
40
lua_setfield (L , -2 , "wait" );
40
41
42
+ lua_pushcfunction (L , ngx_http_lua_uthread_kill );
43
+ lua_setfield (L , -2 , "kill" );
44
+
41
45
lua_setfield (L , -2 , "thread" );
42
46
}
43
47
@@ -181,7 +185,7 @@ ngx_http_lua_uthread_wait(lua_State *L)
181
185
182
186
/* being the last one */
183
187
lua_pushnil (L );
184
- lua_pushliteral (L , "already waited" );
188
+ lua_pushliteral (L , "already waited or killed " );
185
189
return 2 ;
186
190
187
191
default :
@@ -197,4 +201,83 @@ ngx_http_lua_uthread_wait(lua_State *L)
197
201
return lua_yield (L , 0 );
198
202
}
199
203
204
+
205
+ static int
206
+ ngx_http_lua_uthread_kill (lua_State * L )
207
+ {
208
+ lua_State * sub_co ;
209
+ ngx_http_request_t * r ;
210
+ ngx_http_lua_ctx_t * ctx ;
211
+ ngx_http_lua_co_ctx_t * coctx , * sub_coctx ;
212
+
213
+ r = ngx_http_lua_get_req (L );
214
+ if (r == NULL ) {
215
+ return luaL_error (L , "no request found" );
216
+ }
217
+
218
+ ctx = ngx_http_get_module_ctx (r , ngx_http_lua_module );
219
+ if (ctx == NULL ) {
220
+ return luaL_error (L , "no request ctx found" );
221
+ }
222
+
223
+ ngx_http_lua_check_context (L , ctx , NGX_HTTP_LUA_CONTEXT_REWRITE
224
+ | NGX_HTTP_LUA_CONTEXT_ACCESS
225
+ | NGX_HTTP_LUA_CONTEXT_CONTENT
226
+ | NGX_HTTP_LUA_CONTEXT_TIMER );
227
+
228
+ coctx = ctx -> cur_co_ctx ;
229
+
230
+ sub_co = lua_tothread (L , 1 );
231
+ luaL_argcheck (L , sub_co , 1 , "lua thread expected" );
232
+
233
+ sub_coctx = ngx_http_lua_get_co_ctx (sub_co , ctx );
234
+
235
+ if (sub_coctx == NULL ) {
236
+ return luaL_error (L , "no co ctx found" );
237
+ }
238
+
239
+ if (!sub_coctx -> is_uthread ) {
240
+ lua_pushnil (L );
241
+ lua_pushliteral (L , "not user thread" );
242
+ return 2 ;
243
+ }
244
+
245
+ if (sub_coctx -> parent_co_ctx != coctx ) {
246
+ lua_pushnil (L );
247
+ lua_pushliteral (L , "killer not parent" );
248
+ return 2 ;
249
+ }
250
+
251
+ if (sub_coctx -> pending_subreqs > 0 ) {
252
+ lua_pushnil (L );
253
+ lua_pushliteral (L , "pending subrequests" );
254
+ return 2 ;
255
+ }
256
+
257
+ switch (sub_coctx -> co_status ) {
258
+ case NGX_HTTP_LUA_CO_ZOMBIE :
259
+ ngx_http_lua_del_thread (r , L , ctx , sub_coctx );
260
+ ctx -> uthreads -- ;
261
+
262
+ lua_pushnil (L );
263
+ lua_pushliteral (L , "already terminated" );
264
+ return 2 ;
265
+
266
+ case NGX_HTTP_LUA_CO_DEAD :
267
+ lua_pushnil (L );
268
+ lua_pushliteral (L , "already waited or killed" );
269
+ return 2 ;
270
+
271
+ default :
272
+ ngx_http_lua_cleanup_pending_operation (sub_coctx );
273
+ ngx_http_lua_del_thread (r , L , ctx , sub_coctx );
274
+ ctx -> uthreads -- ;
275
+
276
+ lua_pushinteger (L , 1 );
277
+ return 1 ;
278
+ }
279
+
280
+ /* not reacheable */
281
+ }
282
+
200
283
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */
0 commit comments