bugfix: the UDP and TCP cosockets could not keep track of the current Lua coroutine. now we also explicitly clear the current Lua coroutine context in the main request context to ensure that the I/O scheduler can indeed keep track of the current Lua coroutine itself.
This commit is contained in:
Родитель
e49622d8b6
Коммит
e0adfe5ec4
|
@ -528,6 +528,9 @@ ngx_http_lua_socket_tcp_connect(lua_State *L)
|
|||
rctx->timeout = clcf->resolver_timeout;
|
||||
|
||||
u->resolved->ctx = rctx;
|
||||
u->co_ctx = ctx->cur_co_ctx;
|
||||
|
||||
coctx->data = u;
|
||||
|
||||
saved_top = lua_gettop(L);
|
||||
|
||||
|
@ -558,14 +561,11 @@ ngx_http_lua_socket_tcp_connect(lua_State *L)
|
|||
|
||||
/* still resolving */
|
||||
|
||||
u->co_ctx = ctx->cur_co_ctx;
|
||||
u->waiting = 1;
|
||||
u->prepare_retvals = ngx_http_lua_socket_resolve_retval_handler;
|
||||
|
||||
dd("setting data to %p", u);
|
||||
|
||||
coctx->data = u;
|
||||
|
||||
if (ctx->entered_content_phase) {
|
||||
r->write_event_handler = ngx_http_lua_content_wev_handler;
|
||||
}
|
||||
|
@ -600,9 +600,7 @@ ngx_http_lua_socket_resolve_handler(ngx_resolver_ctx_t *ctx)
|
|||
return;
|
||||
}
|
||||
|
||||
dd("ctx->cur_co_ctx = %p", lctx->cur_co_ctx);
|
||||
dd("u->co_ctx = %p", u->co_ctx);
|
||||
|
||||
lctx->cur_co_ctx = u->co_ctx;
|
||||
L = lctx->cur_co_ctx->co;
|
||||
|
||||
waiting = u->waiting;
|
||||
|
@ -2024,6 +2022,7 @@ ngx_http_lua_socket_handle_success(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
ctx->resume_handler = ngx_http_lua_socket_tcp_resume;
|
||||
ctx->cur_co_ctx = u->co_ctx;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"lua tcp socket waking up the current request");
|
||||
|
@ -2060,6 +2059,7 @@ ngx_http_lua_socket_handle_error(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
ctx->resume_handler = ngx_http_lua_socket_tcp_resume;
|
||||
ctx->cur_co_ctx = u->co_ctx;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"lua tcp socket waking up the current request");
|
||||
|
@ -3837,10 +3837,16 @@ ngx_http_lua_socket_tcp_resume(ngx_http_request_t *r)
|
|||
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"lua run subrequests done, resuming lua thread");
|
||||
"lua tcp operation done, resuming lua thread");
|
||||
|
||||
coctx = ctx->cur_co_ctx;
|
||||
|
||||
#if 0
|
||||
ngx_http_lua_probe_info("tcp resume");
|
||||
#endif
|
||||
|
||||
dd("coctx: %p", coctx);
|
||||
|
||||
u = coctx->data;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "ngx_http_lua_util.h"
|
||||
#include "ngx_http_lua_contentby.h"
|
||||
#include "ngx_http_lua_output.h"
|
||||
#include "ngx_http_lua_probe.h"
|
||||
|
||||
|
||||
#define UDP_MAX_DATAGRAM_SIZE 8192
|
||||
|
@ -339,6 +340,7 @@ ngx_http_lua_socket_udp_setpeername(lua_State *L)
|
|||
rctx->data = u;
|
||||
rctx->timeout = clcf->resolver_timeout;
|
||||
|
||||
u->co_ctx = ctx->cur_co_ctx;
|
||||
u->resolved->ctx = rctx;
|
||||
|
||||
saved_top = lua_gettop(L);
|
||||
|
@ -370,7 +372,6 @@ ngx_http_lua_socket_udp_setpeername(lua_State *L)
|
|||
|
||||
/* still resolving */
|
||||
|
||||
u->co_ctx = ctx->cur_co_ctx;
|
||||
u->waiting = 1;
|
||||
u->prepare_retvals = ngx_http_lua_socket_resolve_retval_handler;
|
||||
|
||||
|
@ -407,7 +408,11 @@ ngx_http_lua_socket_resolve_handler(ngx_resolver_ctx_t *ctx)
|
|||
"lua udp socket resolve handler");
|
||||
|
||||
lctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
|
||||
if (lctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
lctx->cur_co_ctx = u->co_ctx;
|
||||
L = lctx->cur_co_ctx->co;
|
||||
|
||||
dd("setting socket_ready to 1");
|
||||
|
@ -1122,6 +1127,7 @@ ngx_http_lua_socket_udp_handle_error(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
ctx->resume_handler = ngx_http_lua_socket_udp_resume;
|
||||
ctx->cur_co_ctx = u->co_ctx;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"lua udp socket waking up the current request");
|
||||
|
@ -1191,6 +1197,7 @@ ngx_http_lua_socket_udp_handle_success(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
ctx->resume_handler = ngx_http_lua_socket_udp_resume;
|
||||
ctx->cur_co_ctx = u->co_ctx;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"lua udp socket waking up the current request");
|
||||
|
@ -1368,10 +1375,14 @@ ngx_http_lua_socket_udp_resume(ngx_http_request_t *r)
|
|||
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"lua run subrequests done, resuming lua thread");
|
||||
"lua udp operation done, resuming lua thread");
|
||||
|
||||
coctx = ctx->cur_co_ctx;
|
||||
|
||||
#if 0
|
||||
ngx_http_lua_probe_info("udp resume");
|
||||
#endif
|
||||
|
||||
u = coctx->data;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
|
|
|
@ -896,6 +896,8 @@ ngx_http_lua_run_thread(lua_State *L, ngx_http_request_t *r,
|
|||
dd("hit! it is the API yield");
|
||||
|
||||
lua_settop(ctx->cur_co_ctx->co, 0);
|
||||
ctx->cur_co_ctx = NULL;
|
||||
|
||||
return NGX_AGAIN;
|
||||
|
||||
case NGX_HTTP_LUA_USER_CORO_RESUME:
|
||||
|
|
|
@ -967,6 +967,13 @@ close: nil closed
|
|||
}
|
||||
--- request
|
||||
GET /test
|
||||
|
||||
--- stap2
|
||||
M(http-lua-info) {
|
||||
printf("tcp resume: %p\n", $coctx)
|
||||
print_ubacktrace()
|
||||
}
|
||||
|
||||
--- response_body
|
||||
failed to connect: connection refused
|
||||
--- error_log
|
||||
|
@ -1167,6 +1174,12 @@ function go(port)
|
|||
ngx.say("failed to receive a line: ", err, " [", part, "]")
|
||||
end
|
||||
end
|
||||
|
||||
--- stap2
|
||||
M(http-lua-info) {
|
||||
printf("tcp resume\n")
|
||||
print_ubacktrace()
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body_like eval
|
||||
|
|
|
@ -5,7 +5,7 @@ use Test::Nginx::Socket;
|
|||
|
||||
repeat_each(2);
|
||||
|
||||
plan tests => repeat_each() * (3 * blocks() + 4);
|
||||
plan tests => repeat_each() * (3 * blocks() + 6);
|
||||
|
||||
our $HtmlDir = html_dir;
|
||||
|
||||
|
@ -252,6 +252,13 @@ function get_udp()
|
|||
|
||||
return udp
|
||||
end
|
||||
|
||||
--- stap2
|
||||
M(http-lua-info) {
|
||||
printf("tcp resume: %p\n", $coctx)
|
||||
print_ubacktrace()
|
||||
}
|
||||
|
||||
--- request
|
||||
GET /main
|
||||
--- response_body_like: \b500\b
|
||||
|
@ -537,3 +544,112 @@ received: hello world
|
|||
--- error_log
|
||||
lua udp socket read timed out
|
||||
|
||||
|
||||
|
||||
=== TEST 10: access the google DNS server (using IP addr)
|
||||
--- config
|
||||
server_tokens off;
|
||||
location /t {
|
||||
content_by_lua '
|
||||
local socket = ngx.socket
|
||||
-- local socket = require "socket"
|
||||
|
||||
local udp = socket.udp()
|
||||
|
||||
udp:settimeout(2000) -- 2 sec
|
||||
|
||||
local ok, err = udp:setpeername("8.8.8.8", 53)
|
||||
if not ok then
|
||||
ngx.say("failed to connect: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
local req = "\\0}\\1\\0\\0\\1\\0\\0\\0\\0\\0\\0\\3www\\6google\\3com\\0\\0\\1\\0\\1"
|
||||
|
||||
-- ngx.print(req)
|
||||
-- do return end
|
||||
|
||||
local ok, err = udp:send(req)
|
||||
if not ok then
|
||||
ngx.say("failed to send: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
local data, err = udp:receive()
|
||||
if not data then
|
||||
ngx.say("failed to receive data: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
if string.match(data, "\\3www\\6google\\3com") then
|
||||
ngx.say("received a good response.")
|
||||
else
|
||||
ngx.say("received a bad response: ", #data, " bytes: ", data)
|
||||
end
|
||||
';
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
received a good response.
|
||||
--- no_error_log
|
||||
[error]
|
||||
--- log_level: debug
|
||||
--- error_log
|
||||
lua udp socket receive buffer size: 8192
|
||||
|
||||
|
||||
|
||||
=== TEST 11: access the google DNS server (using domain names)
|
||||
--- config
|
||||
server_tokens off;
|
||||
resolver $TEST_NGINX_RESOLVER;
|
||||
location /t {
|
||||
content_by_lua '
|
||||
local socket = ngx.socket
|
||||
-- local socket = require "socket"
|
||||
|
||||
local udp = socket.udp()
|
||||
|
||||
udp:settimeout(2000) -- 2 sec
|
||||
|
||||
local ok, err = udp:setpeername("google-public-dns-a.google.com", 53)
|
||||
if not ok then
|
||||
ngx.say("failed to connect: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
local req = "\\0}\\1\\0\\0\\1\\0\\0\\0\\0\\0\\0\\3www\\6google\\3com\\0\\0\\1\\0\\1"
|
||||
|
||||
-- ngx.print(req)
|
||||
-- do return end
|
||||
|
||||
local ok, err = udp:send(req)
|
||||
if not ok then
|
||||
ngx.say("failed to send: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
local data, err = udp:receive()
|
||||
if not data then
|
||||
ngx.say("failed to receive data: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
if string.match(data, "\\3www\\6google\\3com") then
|
||||
ngx.say("received a good response.")
|
||||
else
|
||||
ngx.say("received a bad response: ", #data, " bytes: ", data)
|
||||
end
|
||||
';
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
received a good response.
|
||||
--- no_error_log
|
||||
[error]
|
||||
--- log_level: debug
|
||||
--- error_log
|
||||
lua udp socket receive buffer size: 8192
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче