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:
agentzh (Yichun Zhang) 2012-09-12 17:06:14 -07:00
Родитель e49622d8b6
Коммит e0adfe5ec4
5 изменённых файлов: 158 добавлений и 10 удалений

Просмотреть файл

@ -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