Skip to content

Commit 75c68b2

Browse files
bugfix: posted event handler was called after event memory was freed. (#1982)
1 parent de09fc6 commit 75c68b2

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

src/ngx_http_lua_semaphore.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,8 +466,11 @@ ngx_http_lua_sema_handler(ngx_event_t *ev)
466466

467467
sem = ev->data;
468468

469+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
470+
"semaphore handler: wait queue: %sempty, resource count: %d",
471+
ngx_queue_empty(&sem->wait_queue) ? "" : "not ",
472+
sem->resource_count);
469473
while (!ngx_queue_empty(&sem->wait_queue) && sem->resource_count > 0) {
470-
471474
q = ngx_queue_head(&sem->wait_queue);
472475
ngx_queue_remove(q);
473476

@@ -566,6 +569,10 @@ ngx_http_lua_ffi_sema_gc(ngx_http_lua_sema_t *sem)
566569
"destroyed", sem);
567570
}
568571

572+
if (sem->sem_event.posted) {
573+
ngx_delete_posted_event(&sem->sem_event);
574+
}
575+
569576
ngx_http_lua_free_sema(sem);
570577
}
571578

t/154-semaphore.t

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,53 @@ hello, world
118118
--- no_shutdown_error_log
119119
semaphore gc wait queue is not empty
120120
--- SKIP
121+
122+
123+
124+
=== TEST 3: exit before post_handler was called
125+
If gc is called before the ngx_http_lua_sema_handler and free the sema memory
126+
ngx_http_lua_sema_handler would use the freed memory.
127+
--- config
128+
location /up {
129+
content_by_lua_block {
130+
local semaphore = require "ngx.semaphore"
131+
local sem = semaphore.new()
132+
133+
local function sem_wait()
134+
ngx.log(ngx.ERR, "ngx.sem wait start")
135+
local ok, err = sem:wait(10)
136+
if not ok then
137+
ngx.log(ngx.ERR, "ngx.sem wait err: ", err)
138+
else
139+
ngx.log(ngx.ERR, "ngx.sem wait success")
140+
end
141+
end
142+
local co = ngx.thread.spawn(sem_wait)
143+
ngx.log(ngx.ERR, "ngx.sem post start")
144+
sem:post()
145+
ngx.log(ngx.ERR, "ngx.sem post end")
146+
ngx.say("hello")
147+
ngx.exit(200)
148+
ngx.say("not reach here")
149+
}
150+
}
151+
152+
location /t {
153+
content_by_lua_block {
154+
local res = ngx.location.capture("/up")
155+
collectgarbage()
156+
ngx.print(res.body)
157+
}
158+
}
159+
160+
--- request
161+
GET /t
162+
--- response_body
163+
hello
164+
--- grep_error_log eval: qr/(ngx.sem .*?,|http close request|semaphore handler: wait queue: empty, resource count: 1|in lua gc, semaphore)/
165+
--- grep_error_log_out
166+
ngx.sem wait start,
167+
ngx.sem post start,
168+
ngx.sem post end,
169+
in lua gc, semaphore
170+
http close request

0 commit comments

Comments
 (0)