Skip to content

Commit 761ddca

Browse files
spacewanderthibaultcha
authored andcommitted
bugfix: ensured we cleanup up aborted queued connect operations.
Signed-off-by: Thibault Charbonnier <[email protected]>
1 parent 8edb21a commit 761ddca

File tree

2 files changed

+110
-18
lines changed

2 files changed

+110
-18
lines changed

src/ngx_http_lua_socket_tcp.c

+63-18
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ static ngx_int_t ngx_http_lua_socket_tcp_read_resume(ngx_http_request_t *r);
140140
static ngx_int_t ngx_http_lua_socket_tcp_write_resume(ngx_http_request_t *r);
141141
static ngx_int_t ngx_http_lua_socket_tcp_resume_helper(ngx_http_request_t *r,
142142
int socket_op);
143+
static void ngx_http_lua_tcp_queue_conn_op_cleanup(void *data);
143144
static void ngx_http_lua_tcp_resolve_cleanup(void *data);
144145
static void ngx_http_lua_coctx_cleanup(void *data);
145146
static void ngx_http_lua_socket_free_pool(ngx_log_t *log,
@@ -630,6 +631,10 @@ ngx_http_lua_socket_tcp_connect_helper(lua_State *L,
630631
u->write_co_ctx = ctx->cur_co_ctx;
631632

632633
conn_op_ctx->u = u;
634+
ctx->cur_co_ctx->cleanup =
635+
ngx_http_lua_tcp_queue_conn_op_cleanup;
636+
ctx->cur_co_ctx->data = conn_op_ctx;
637+
633638
ngx_memzero(&conn_op_ctx->event, sizeof(ngx_event_t));
634639
conn_op_ctx->event.handler =
635640
ngx_http_lua_socket_tcp_conn_op_timeout_handler;
@@ -3977,25 +3982,10 @@ ngx_http_lua_socket_tcp_resume_conn_op(ngx_http_lua_socket_pool_t *spool)
39773982
* is exiting.
39783983
*/
39793984
if (ngx_queue_empty(&spool->wait_connect_op)) {
3980-
#if (NGX_DEBUG)
3981-
ngx_http_lua_assert(!(spool->backlog >= 0
3982-
&& spool->connections > spool->size));
3983-
3984-
#else
3985-
if (spool->backlog >= 0 && spool->connections > spool->size) {
3986-
ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0,
3987-
"lua tcp socket connections count mismatched for "
3988-
"connection pool \"%s\", connections: %i, size: %i",
3989-
spool->key, spool->connections, spool->size);
3990-
spool->connections = spool->size;
3991-
}
3992-
#endif
3993-
39943985
return;
39953986
}
39963987

39973988
q = ngx_queue_head(&spool->wait_connect_op);
3998-
ngx_queue_remove(q);
39993989
conn_op_ctx = ngx_queue_data(q, ngx_http_lua_socket_tcp_conn_op_ctx_t,
40003990
queue);
40013991
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
@@ -4034,27 +4024,52 @@ ngx_http_lua_socket_tcp_conn_op_ctx_cleanup(void *data)
40344024
static void
40354025
ngx_http_lua_socket_tcp_conn_op_resume_handler(ngx_event_t *ev)
40364026
{
4037-
ngx_http_lua_socket_tcp_upstream_t *u;
4038-
ngx_http_lua_ctx_t *ctx;
4027+
ngx_queue_t *q;
40394028
ngx_connection_t *c;
4029+
ngx_http_lua_ctx_t *ctx;
40404030
ngx_http_request_t *r;
40414031
ngx_http_cleanup_t *cln;
40424032
ngx_http_lua_co_ctx_t *coctx;
4033+
ngx_http_lua_socket_pool_t *spool;
4034+
ngx_http_lua_socket_tcp_upstream_t *u;
40434035
ngx_http_lua_socket_tcp_conn_op_ctx_t *conn_op_ctx;
40444036

40454037
conn_op_ctx = ev->data;
40464038
u = conn_op_ctx->u;
40474039
r = u->request;
4040+
spool = u->socket_pool;
4041+
4042+
if (ngx_queue_empty(&spool->wait_connect_op)) {
4043+
#if (NGX_DEBUG)
4044+
ngx_http_lua_assert(!(spool->backlog >= 0
4045+
&& spool->connections > spool->size));
4046+
4047+
#else
4048+
if (spool->backlog >= 0 && spool->connections > spool->size) {
4049+
ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0,
4050+
"lua tcp socket connections count mismatched for "
4051+
"connection pool \"%s\", connections: %i, size: %i",
4052+
spool->key, spool->connections, spool->size);
4053+
spool->connections = spool->size;
4054+
}
4055+
#endif
4056+
4057+
return;
4058+
}
4059+
4060+
q = ngx_queue_head(&spool->wait_connect_op);
4061+
ngx_queue_remove(q);
40484062

40494063
coctx = u->write_co_ctx;
40504064
coctx->cleanup = NULL;
40514065
/* note that we store conn_op_ctx in coctx->data instead of u */
40524066
coctx->data = conn_op_ctx;
4067+
/* clear ngx_http_lua_tcp_queue_conn_op_cleanup */
40534068
u->write_co_ctx = NULL;
40544069

40554070
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
40564071
if (ctx == NULL) {
4057-
ngx_queue_insert_head(&u->socket_pool->cache_connect_op,
4072+
ngx_queue_insert_head(&spool->cache_connect_op,
40584073
&conn_op_ctx->queue);
40594074
return;
40604075
}
@@ -6021,6 +6036,36 @@ ngx_http_lua_socket_tcp_resume_helper(ngx_http_request_t *r, int socket_op)
60216036
}
60226037

60236038

6039+
static void
6040+
ngx_http_lua_tcp_queue_conn_op_cleanup(void *data)
6041+
{
6042+
ngx_http_lua_co_ctx_t *coctx = data;
6043+
ngx_http_lua_socket_tcp_upstream_t *u;
6044+
ngx_http_lua_socket_tcp_conn_op_ctx_t *conn_op_ctx;
6045+
6046+
conn_op_ctx = coctx->data;
6047+
u = conn_op_ctx->u;
6048+
6049+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
6050+
"lua tcp socket abort queueing, conn_op_ctx: %p, u: %p",
6051+
conn_op_ctx, u);
6052+
6053+
if (conn_op_ctx->event.posted) {
6054+
ngx_delete_posted_event(&conn_op_ctx->event);
6055+
6056+
} else if (conn_op_ctx->event.timer_set) {
6057+
ngx_del_timer(&conn_op_ctx->event);
6058+
}
6059+
6060+
ngx_queue_remove(&conn_op_ctx->queue);
6061+
ngx_queue_insert_head(&u->socket_pool->cache_connect_op,
6062+
&conn_op_ctx->queue);
6063+
6064+
u->socket_pool->connections--;
6065+
ngx_http_lua_socket_tcp_resume_conn_op(u->socket_pool);
6066+
}
6067+
6068+
60246069
static void
60256070
ngx_http_lua_tcp_resolve_cleanup(void *data)
60266071
{

t/068-socket-keepalive.t

+47
Original file line numberDiff line numberDiff line change
@@ -2909,3 +2909,50 @@ GET /t
29092909
[error]
29102910
--- response_body
29112911
ok
2912+
2913+
2914+
2915+
=== TEST 52: conn queuing: clean up pending connect operations which are in queue
2916+
--- config
2917+
set $port $TEST_NGINX_MEMCACHED_PORT;
2918+
2919+
location /sub {
2920+
content_by_lua_block {
2921+
local opts = {pool = "test", pool_size = 1, backlog = 1}
2922+
local sock, err = ngx.socket.connect("127.0.0.1", ngx.var.port, opts)
2923+
if not sock then
2924+
ngx.say("connect failed: " .. err)
2925+
return
2926+
end
2927+
2928+
local function f()
2929+
assert(ngx.socket.connect("127.0.0.1", ngx.var.port, opts))
2930+
end
2931+
2932+
local th = ngx.thread.spawn(f)
2933+
local ok, err = ngx.thread.kill(th)
2934+
if not ok then
2935+
ngx.log(ngx.ERR, "kill thread failed: ", err)
2936+
return
2937+
end
2938+
2939+
sock:close()
2940+
}
2941+
}
2942+
2943+
location /t {
2944+
content_by_lua_block {
2945+
ngx.location.capture("/sub")
2946+
-- let pending connect operation resumes first
2947+
ngx.sleep(0)
2948+
ngx.say("ok")
2949+
}
2950+
}
2951+
--- request
2952+
GET /t
2953+
--- no_error_log
2954+
[error]
2955+
--- error_log
2956+
lua tcp socket abort queueing
2957+
--- response_body
2958+
ok

0 commit comments

Comments
 (0)