Using malloc/free for the http fields hash.
This is required due to lack of a graceful shutdown: there is a small gap between the runtime's memory pool release and router process's exit. Thus, a worker thread may start processing a request between these two operations, which may result in an http fields hash access and subsequent crash. To simplify issue reproduction, it makes sense to add a 2 sec sleep before exit() in nxt_runtime_exit().
This commit is contained in:
@@ -130,14 +130,11 @@ nxt_controller_start(nxt_task_t *task, void *data)
|
||||
nxt_mp_t *mp;
|
||||
nxt_int_t ret;
|
||||
nxt_str_t *json;
|
||||
nxt_runtime_t *rt;
|
||||
nxt_conf_value_t *conf;
|
||||
nxt_conf_validation_t vldt;
|
||||
nxt_controller_init_t *init;
|
||||
|
||||
rt = task->thread->runtime;
|
||||
|
||||
ret = nxt_http_fields_hash(&nxt_controller_fields_hash, rt->mem_pool,
|
||||
ret = nxt_http_fields_hash(&nxt_controller_fields_hash,
|
||||
nxt_controller_request_fields,
|
||||
nxt_nitems(nxt_controller_request_fields));
|
||||
|
||||
|
||||
@@ -186,16 +186,16 @@ static nxt_http_field_proc_t nxt_h1p_peer_fields[] = {
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_h1p_init(nxt_task_t *task, nxt_runtime_t *rt)
|
||||
nxt_h1p_init(nxt_task_t *task)
|
||||
{
|
||||
nxt_int_t ret;
|
||||
|
||||
ret = nxt_http_fields_hash(&nxt_h1p_fields_hash, rt->mem_pool,
|
||||
ret = nxt_http_fields_hash(&nxt_h1p_fields_hash,
|
||||
nxt_h1p_fields, nxt_nitems(nxt_h1p_fields));
|
||||
|
||||
if (nxt_fast_path(ret == NXT_OK)) {
|
||||
ret = nxt_http_fields_hash(&nxt_h1p_peer_fields_hash,
|
||||
rt->mem_pool, nxt_h1p_peer_fields,
|
||||
nxt_h1p_peer_fields,
|
||||
nxt_nitems(nxt_h1p_peer_fields));
|
||||
}
|
||||
|
||||
|
||||
@@ -245,9 +245,9 @@ nxt_http_date(u_char *buf, struct tm *tm)
|
||||
}
|
||||
|
||||
|
||||
nxt_int_t nxt_http_init(nxt_task_t *task, nxt_runtime_t *rt);
|
||||
nxt_int_t nxt_h1p_init(nxt_task_t *task, nxt_runtime_t *rt);
|
||||
nxt_int_t nxt_http_response_hash_init(nxt_task_t *task, nxt_runtime_t *rt);
|
||||
nxt_int_t nxt_http_init(nxt_task_t *task);
|
||||
nxt_int_t nxt_h1p_init(nxt_task_t *task);
|
||||
nxt_int_t nxt_http_response_hash_init(nxt_task_t *task);
|
||||
|
||||
void nxt_http_conn_init(nxt_task_t *task, void *obj, void *data);
|
||||
nxt_http_request_t *nxt_http_request_create(nxt_task_t *task);
|
||||
|
||||
@@ -22,8 +22,6 @@ static nxt_int_t nxt_http_parse_field_end(nxt_http_request_parse_t *rp,
|
||||
static nxt_int_t nxt_http_parse_complex_target(nxt_http_request_parse_t *rp);
|
||||
|
||||
static nxt_int_t nxt_http_field_hash_test(nxt_lvlhsh_query_t *lhq, void *data);
|
||||
static void *nxt_http_field_hash_alloc(void *pool, size_t size);
|
||||
static void nxt_http_field_hash_free(void *pool, void *p);
|
||||
|
||||
static nxt_int_t nxt_http_field_hash_collision(nxt_lvlhsh_query_t *lhq,
|
||||
void *data);
|
||||
@@ -1133,8 +1131,8 @@ const nxt_lvlhsh_proto_t nxt_http_fields_hash_proto nxt_aligned(64) = {
|
||||
NXT_LVLHSH_BUCKET_SIZE(64),
|
||||
{ NXT_HTTP_FIELD_LVLHSH_SHIFT, 0, 0, 0, 0, 0, 0, 0 },
|
||||
nxt_http_field_hash_test,
|
||||
nxt_http_field_hash_alloc,
|
||||
nxt_http_field_hash_free,
|
||||
nxt_lvlhsh_alloc,
|
||||
nxt_lvlhsh_free,
|
||||
};
|
||||
|
||||
|
||||
@@ -1153,20 +1151,6 @@ nxt_http_field_hash_test(nxt_lvlhsh_query_t *lhq, void *data)
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
nxt_http_field_hash_alloc(void *pool, size_t size)
|
||||
{
|
||||
return nxt_mp_align(pool, size, size);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nxt_http_field_hash_free(void *pool, void *p)
|
||||
{
|
||||
nxt_mp_free(pool, p);
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_http_field_hash_collision(nxt_lvlhsh_query_t *lhq, void *data)
|
||||
{
|
||||
@@ -1175,7 +1159,7 @@ nxt_http_field_hash_collision(nxt_lvlhsh_query_t *lhq, void *data)
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_http_fields_hash(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
|
||||
nxt_http_fields_hash(nxt_lvlhsh_t *hash,
|
||||
nxt_http_field_proc_t items[], nxt_uint_t count)
|
||||
{
|
||||
u_char ch;
|
||||
@@ -1187,7 +1171,6 @@ nxt_http_fields_hash(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
|
||||
|
||||
lhq.replace = 0;
|
||||
lhq.proto = &nxt_http_fields_hash_proto;
|
||||
lhq.pool = mp;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
key = NXT_HTTP_FIELD_HASH_INIT;
|
||||
@@ -1214,7 +1197,7 @@ nxt_http_fields_hash(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
|
||||
|
||||
|
||||
nxt_uint_t
|
||||
nxt_http_fields_hash_collisions(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
|
||||
nxt_http_fields_hash_collisions(nxt_lvlhsh_t *hash,
|
||||
nxt_http_field_proc_t items[], nxt_uint_t count, nxt_bool_t level)
|
||||
{
|
||||
u_char ch;
|
||||
@@ -1229,7 +1212,6 @@ nxt_http_fields_hash_collisions(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
|
||||
|
||||
lhq.replace = 0;
|
||||
lhq.proto = &proto;
|
||||
lhq.pool = mp;
|
||||
|
||||
mask = level ? (1 << NXT_HTTP_FIELD_LVLHSH_SHIFT) - 1 : 0xFFFF;
|
||||
|
||||
|
||||
@@ -102,9 +102,9 @@ nxt_int_t nxt_http_parse_request(nxt_http_request_parse_t *rp,
|
||||
nxt_int_t nxt_http_parse_fields(nxt_http_request_parse_t *rp,
|
||||
nxt_buf_mem_t *b);
|
||||
|
||||
nxt_int_t nxt_http_fields_hash(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
|
||||
nxt_int_t nxt_http_fields_hash(nxt_lvlhsh_t *hash,
|
||||
nxt_http_field_proc_t items[], nxt_uint_t count);
|
||||
nxt_uint_t nxt_http_fields_hash_collisions(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
|
||||
nxt_uint_t nxt_http_fields_hash_collisions(nxt_lvlhsh_t *hash,
|
||||
nxt_http_field_proc_t items[], nxt_uint_t count, nxt_bool_t level);
|
||||
nxt_int_t nxt_http_fields_process(nxt_list_t *fields, nxt_lvlhsh_t *hash,
|
||||
void *ctx);
|
||||
|
||||
@@ -36,17 +36,17 @@ nxt_time_string_t nxt_http_date_cache = {
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_http_init(nxt_task_t *task, nxt_runtime_t *rt)
|
||||
nxt_http_init(nxt_task_t *task)
|
||||
{
|
||||
nxt_int_t ret;
|
||||
|
||||
ret = nxt_h1p_init(task, rt);
|
||||
ret = nxt_h1p_init(task);
|
||||
|
||||
if (ret != NXT_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return nxt_http_response_hash_init(task, rt);
|
||||
return nxt_http_response_hash_init(task);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,9 +34,9 @@ static nxt_http_field_proc_t nxt_response_fields[] = {
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_http_response_hash_init(nxt_task_t *task, nxt_runtime_t *rt)
|
||||
nxt_http_response_hash_init(nxt_task_t *task)
|
||||
{
|
||||
return nxt_http_fields_hash(&nxt_response_fields_hash, rt->mem_pool,
|
||||
return nxt_http_fields_hash(&nxt_response_fields_hash,
|
||||
nxt_response_fields, nxt_nitems(nxt_response_fields));
|
||||
}
|
||||
|
||||
|
||||
@@ -303,7 +303,7 @@ nxt_router_start(nxt_task_t *task, void *data)
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = nxt_http_init(task, rt);
|
||||
ret = nxt_http_init(task);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -510,7 +510,7 @@ static nxt_str_t nxt_http_test_big_request = nxt_string(
|
||||
nxt_int_t
|
||||
nxt_http_parse_test(nxt_thread_t *thr)
|
||||
{
|
||||
nxt_mp_t *mp, *mp_temp;
|
||||
nxt_mp_t *mp_temp;
|
||||
nxt_int_t rc;
|
||||
nxt_uint_t i, colls, lvl_colls;
|
||||
nxt_lvlhsh_t hash;
|
||||
@@ -519,12 +519,7 @@ nxt_http_parse_test(nxt_thread_t *thr)
|
||||
|
||||
nxt_thread_time_update(thr);
|
||||
|
||||
mp = nxt_mp_create(1024, 128, 256, 32);
|
||||
if (mp == NULL) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
rc = nxt_http_fields_hash(&nxt_http_test_fields_hash, mp,
|
||||
rc = nxt_http_fields_hash(&nxt_http_test_fields_hash,
|
||||
nxt_http_test_fields,
|
||||
nxt_nitems(nxt_http_test_fields));
|
||||
if (rc != NXT_OK) {
|
||||
@@ -569,14 +564,14 @@ nxt_http_parse_test(nxt_thread_t *thr)
|
||||
|
||||
nxt_memzero(&hash, sizeof(nxt_lvlhsh_t));
|
||||
|
||||
colls = nxt_http_fields_hash_collisions(&hash, mp,
|
||||
colls = nxt_http_fields_hash_collisions(&hash,
|
||||
nxt_http_test_bench_fields,
|
||||
nxt_nitems(nxt_http_test_bench_fields),
|
||||
0);
|
||||
|
||||
nxt_memzero(&hash, sizeof(nxt_lvlhsh_t));
|
||||
|
||||
lvl_colls = nxt_http_fields_hash_collisions(&hash, mp,
|
||||
lvl_colls = nxt_http_fields_hash_collisions(&hash,
|
||||
nxt_http_test_bench_fields,
|
||||
nxt_nitems(nxt_http_test_bench_fields),
|
||||
1);
|
||||
@@ -587,7 +582,7 @@ nxt_http_parse_test(nxt_thread_t *thr)
|
||||
|
||||
nxt_memzero(&hash, sizeof(nxt_lvlhsh_t));
|
||||
|
||||
rc = nxt_http_fields_hash(&hash, mp, nxt_http_test_bench_fields,
|
||||
rc = nxt_http_fields_hash(&hash, nxt_http_test_bench_fields,
|
||||
nxt_nitems(nxt_http_test_bench_fields));
|
||||
if (rc != NXT_OK) {
|
||||
return NXT_ERROR;
|
||||
@@ -607,8 +602,6 @@ nxt_http_parse_test(nxt_thread_t *thr)
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
nxt_mp_destroy(mp);
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user