Skip to content

Commit fdda724

Browse files
committed
bugfix: prevent uthread crash by checking coroutine reference before deletion
1 parent cd24241 commit fdda724

1 file changed

Lines changed: 81 additions & 0 deletions

File tree

t/127-uthread-kill.t

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ plan tests => repeat_each() * (blocks() * 5 + 1);
1111

1212
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
1313
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= '11211';
14+
$ENV{TEST_NGINX_REDIS_PORT} ||= '6379';
1415

1516
#no_shuffle();
1617
no_long_string();
@@ -313,3 +314,83 @@ thread created: zombie
313314
[alert]
314315
stream lua tcp socket abort resolver
315316
--- error_log
317+
318+
319+
320+
=== TEST 7: no phantom uthreads decrement after killing parent uthread
321+
--- stream_server_config
322+
content_by_lua_block {
323+
local redis_port = $TEST_NGINX_REDIS_PORT
324+
local dns_threads = {}
325+
326+
dns_threads[1] = ngx.thread.spawn(function()
327+
local sock = ngx.socket.tcp()
328+
sock:settimeout(2000)
329+
local ok, err = sock:connect("127.0.0.1", redis_port)
330+
if not ok then
331+
return nil, err
332+
end
333+
334+
sock:send("PING\r\n")
335+
local line = sock:receive()
336+
sock:setkeepalive()
337+
return line
338+
end)
339+
340+
dns_threads[2] = ngx.thread.spawn(function()
341+
local child = coroutine.create(function()
342+
local sock = ngx.socket.tcp()
343+
sock:settimeout(2000)
344+
local ok, err = sock:connect("127.0.0.1", redis_port)
345+
if not ok then
346+
return nil, err
347+
end
348+
349+
sock:send("PING\r\n")
350+
local line = sock:receive()
351+
sock:setkeepalive()
352+
return line
353+
end)
354+
355+
local ok, res = coroutine.resume(child)
356+
return res
357+
end)
358+
359+
ngx.thread.wait(dns_threads[1], dns_threads[2])
360+
361+
for _, t in ipairs(dns_threads) do
362+
ngx.thread.kill(t)
363+
end
364+
365+
local probe_threads = {}
366+
for i = 1, 10 do
367+
probe_threads[i] = ngx.thread.spawn(function()
368+
local sock = ngx.socket.tcp()
369+
sock:settimeout(2000)
370+
local ok, err = sock:connect("127.0.0.1", redis_port)
371+
if not ok then
372+
return nil, err
373+
end
374+
375+
sock:send("PING\r\n")
376+
local line = sock:receive()
377+
sock:setkeepalive()
378+
return line
379+
end)
380+
end
381+
382+
local ok_count = 0
383+
for i = 1, #probe_threads do
384+
local ok, res = ngx.thread.wait(probe_threads[i])
385+
if ok and res then
386+
ok_count = ok_count + 1
387+
end
388+
end
389+
390+
ngx.say("ok_count=", ok_count)
391+
}
392+
--- stream_response
393+
ok_count=10
394+
--- no_error_log
395+
[error]
396+
[alert]

0 commit comments

Comments
 (0)