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
|
use Test::Nginx::Socket::Lua::Stream;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3) + 1;
log_level("debug");
no_long_string();
#no_diff();
run_tests();
__DATA__
=== TEST 1: timer + shutdown error log
--- stream_server_config
content_by_lua_block {
local function test(pre)
local semaphore = require "ngx.semaphore"
local sem = semaphore.new()
local function sem_wait()
local ok, err = sem:wait(10)
if not ok then
ngx.log(ngx.ERR, "err: ", err)
else
ngx.log(ngx.info, "wait success")
end
end
while not ngx.worker.exiting() do
local co = ngx.thread.spawn(sem_wait)
ngx.thread.wait(co)
end
end
local ok, err = ngx.timer.at(0, test)
ngx.log(ngx.INFO, "hello, world")
ngx.say("time: ", ok)
}
--- request
GET /t
--- stream_response_like eval
time: 1
--- grep_error_log eval: qr/hello, world|semaphore gc wait queue is not empty/
--- grep_error_log_out
hello, world
--- shutdown_error_log
--- no_shutdown_error_log
semaphore gc wait queue is not empty
=== TEST 2: timer + shutdown error log (lua code cache off)
FIXME: this test case leaks memory.
--- stream_server_config
lua_code_cache off;
content_by_lua_block {
local function test(pre)
local semaphore = require "ngx.semaphore"
local sem = semaphore.new()
local function sem_wait()
local ok, err = sem:wait(10)
if not ok then
ngx.log(ngx.ERR, "err: ", err)
else
ngx.log(ngx.ERR, "wait success")
end
end
while not ngx.worker.exiting() do
local co = ngx.thread.spawn(sem_wait)
ngx.thread.wait(co)
end
end
local ok, err = ngx.timer.at(0, test)
ngx.log(ngx.ERR, "hello, world")
ngx.say("time: ", ok)
}
--- request
GET /test
--- stream_response_like eval
time: 1
--- grep_error_log eval: qr/hello, world|semaphore gc wait queue is not empty/
--- grep_error_log_out
hello, world
--- shutdown_error_log
--- no_shutdown_error_log
semaphore gc wait queue is not empty
--- SKIP
=== TEST 3: exit before post_handler was called
If gc is called before the ngx_http_lua_sema_handler and free the sema memory
ngx_http_lua_sema_handler would use the freed memory.
--- stream_server_config
content_by_lua_block {
local semaphore = require "ngx.semaphore"
local sem = semaphore.new()
local function sem_wait()
ngx.log(ngx.INFO, "ngx.sem wait start")
local ok, err = sem:wait(10)
if not ok then
ngx.log(ngx.ERR, "ngx.sem wait err: ", err)
else
ngx.log(ngx.INFO, "ngx.sem wait success")
end
end
local co = ngx.thread.spawn(sem_wait)
ngx.log(ngx.INFO, "ngx.sem post start")
sem:post()
ngx.log(ngx.INFO, "ngx.sem post end")
ngx.say("hello")
ngx.exit(200)
ngx.say("not reach here")
}
--- request
GET /t
--- stream_response_like
hello
--- grep_error_log eval: qr/(ngx.sem .*?,|close stream connection|semaphore handler: wait queue: empty, resource count: 1)/
--- grep_error_log_out
ngx.sem wait start,
ngx.sem post start,
ngx.sem post end,
close stream connection
semaphore handler: wait queue: empty, resource count: 1
|