NJS: adding the missing vm destruction.
This commit fixed the njs memory leak happened in the config validation, updating and http requests.
This commit is contained in:
@@ -25,6 +25,12 @@ NGINX Unit updated to 1.29.1.
|
|||||||
</para>
|
</para>
|
||||||
</change>
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para>
|
||||||
|
memory leak related to NJS.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
</changes>
|
</changes>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1284,25 +1284,35 @@ nxt_conf_validate(nxt_conf_validation_t *vldt)
|
|||||||
|
|
||||||
vldt->tstr_state = nxt_tstr_state_new(vldt->pool, 1);
|
vldt->tstr_state = nxt_tstr_state_new(vldt->pool, 1);
|
||||||
if (nxt_slow_path(vldt->tstr_state == NULL)) {
|
if (nxt_slow_path(vldt->tstr_state == NULL)) {
|
||||||
return NXT_ERROR;
|
ret = NXT_ERROR;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nxt_conf_vldt_type(vldt, NULL, vldt->conf, NXT_CONF_VLDT_OBJECT);
|
ret = nxt_conf_vldt_type(vldt, NULL, vldt->conf, NXT_CONF_VLDT_OBJECT);
|
||||||
if (ret != NXT_OK) {
|
if (ret != NXT_OK) {
|
||||||
return ret;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nxt_conf_vldt_object(vldt, vldt->conf, nxt_conf_vldt_root_members);
|
ret = nxt_conf_vldt_object(vldt, vldt->conf, nxt_conf_vldt_root_members);
|
||||||
if (ret != NXT_OK) {
|
if (ret != NXT_OK) {
|
||||||
return ret;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nxt_tstr_state_done(vldt->tstr_state, error);
|
ret = nxt_tstr_state_done(vldt->tstr_state, error);
|
||||||
if (ret != NXT_OK) {
|
if (ret != NXT_OK) {
|
||||||
return nxt_conf_vldt_error(vldt, "%s", error);
|
ret = nxt_conf_vldt_error(vldt, "%s", error);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nxt_tstr_state_release(vldt->tstr_state);
|
||||||
|
|
||||||
return NXT_OK;
|
return NXT_OK;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
|
||||||
|
nxt_tstr_state_release(vldt->tstr_state);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -833,6 +833,10 @@ nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data)
|
|||||||
r->body->file->fd = -1;
|
r->body->file->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r->tstr_query != NULL) {
|
||||||
|
nxt_tstr_query_release(r->tstr_query);
|
||||||
|
}
|
||||||
|
|
||||||
if (nxt_fast_path(proto.any != NULL)) {
|
if (nxt_fast_path(proto.any != NULL)) {
|
||||||
protocol = r->protocol;
|
protocol = r->protocol;
|
||||||
|
|
||||||
|
|||||||
17
src/nxt_js.c
17
src/nxt_js.c
@@ -46,6 +46,7 @@ nxt_js_conf_new(nxt_mp_t *mp)
|
|||||||
|
|
||||||
jcf->funcs = nxt_array_create(mp, 4, sizeof(nxt_str_t));
|
jcf->funcs = nxt_array_create(mp, 4, sizeof(nxt_str_t));
|
||||||
if (nxt_slow_path(jcf->funcs == NULL)) {
|
if (nxt_slow_path(jcf->funcs == NULL)) {
|
||||||
|
njs_vm_destroy(jcf->vm);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +54,13 @@ nxt_js_conf_new(nxt_mp_t *mp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nxt_js_conf_release(nxt_js_conf_t *jcf)
|
||||||
|
{
|
||||||
|
njs_vm_destroy(jcf->vm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nxt_js_set_proto(nxt_js_conf_t *jcf, njs_external_t *proto, njs_uint_t n)
|
nxt_js_set_proto(nxt_js_conf_t *jcf, njs_external_t *proto, njs_uint_t n)
|
||||||
{
|
{
|
||||||
@@ -297,3 +305,12 @@ nxt_js_call(nxt_task_t *task, nxt_js_cache_t *cache, nxt_js_t *js,
|
|||||||
|
|
||||||
return NXT_OK;
|
return NXT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nxt_js_release(nxt_js_cache_t *cache)
|
||||||
|
{
|
||||||
|
if (cache->vm != NULL) {
|
||||||
|
njs_vm_destroy(cache->vm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,12 +22,14 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
nxt_js_conf_t *nxt_js_conf_new(nxt_mp_t *mp);
|
nxt_js_conf_t *nxt_js_conf_new(nxt_mp_t *mp);
|
||||||
|
void nxt_js_conf_release(nxt_js_conf_t *jcf);
|
||||||
void nxt_js_set_proto(nxt_js_conf_t *jcf, njs_external_t *proto, nxt_uint_t n);
|
void nxt_js_set_proto(nxt_js_conf_t *jcf, njs_external_t *proto, nxt_uint_t n);
|
||||||
nxt_js_t *nxt_js_add_tpl(nxt_js_conf_t *jcf, nxt_str_t *str, nxt_bool_t strz);
|
nxt_js_t *nxt_js_add_tpl(nxt_js_conf_t *jcf, nxt_str_t *str, nxt_bool_t strz);
|
||||||
nxt_int_t nxt_js_compile(nxt_js_conf_t *jcf);
|
nxt_int_t nxt_js_compile(nxt_js_conf_t *jcf);
|
||||||
nxt_int_t nxt_js_test(nxt_js_conf_t *jcf, nxt_str_t *str, u_char *error);
|
nxt_int_t nxt_js_test(nxt_js_conf_t *jcf, nxt_str_t *str, u_char *error);
|
||||||
nxt_int_t nxt_js_call(nxt_task_t *task, nxt_js_cache_t *cache, nxt_js_t *js,
|
nxt_int_t nxt_js_call(nxt_task_t *task, nxt_js_cache_t *cache, nxt_js_t *js,
|
||||||
nxt_str_t *str, void *ctx);
|
nxt_str_t *str, void *ctx);
|
||||||
|
void nxt_js_release(nxt_js_cache_t *cache);
|
||||||
|
|
||||||
|
|
||||||
extern njs_int_t nxt_js_proto_id;
|
extern njs_int_t nxt_js_proto_id;
|
||||||
|
|||||||
@@ -1111,6 +1111,10 @@ temp_fail:
|
|||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
|
if (rtcf->tstr_state != NULL) {
|
||||||
|
nxt_tstr_state_release(rtcf->tstr_state);
|
||||||
|
}
|
||||||
|
|
||||||
nxt_mp_destroy(mp);
|
nxt_mp_destroy(mp);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -3794,6 +3798,8 @@ nxt_router_conf_release(nxt_task_t *task, nxt_socket_conf_joint_t *joint)
|
|||||||
|
|
||||||
nxt_router_access_log_release(task, lock, rtcf->access_log);
|
nxt_router_access_log_release(task, lock, rtcf->access_log);
|
||||||
|
|
||||||
|
nxt_tstr_state_release(rtcf->tstr_state);
|
||||||
|
|
||||||
nxt_mp_thread_adopt(rtcf->mem_pool);
|
nxt_mp_thread_adopt(rtcf->mem_pool);
|
||||||
|
|
||||||
nxt_mp_destroy(rtcf->mem_pool);
|
nxt_mp_destroy(rtcf->mem_pool);
|
||||||
|
|||||||
@@ -194,6 +194,15 @@ nxt_tstr_state_done(nxt_tstr_state_t *state, u_char *error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nxt_tstr_state_release(nxt_tstr_state_t *state)
|
||||||
|
{
|
||||||
|
#if (NXT_HAVE_NJS)
|
||||||
|
nxt_js_conf_release(state->jcf);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
nxt_bool_t
|
nxt_bool_t
|
||||||
nxt_tstr_is_const(nxt_tstr_t *tstr)
|
nxt_tstr_is_const(nxt_tstr_t *tstr)
|
||||||
{
|
{
|
||||||
@@ -315,3 +324,12 @@ nxt_tstr_query_handle(nxt_task_t *task, nxt_tstr_query_t *query,
|
|||||||
task, query->ctx, query->data);
|
task, query->ctx, query->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nxt_tstr_query_release(nxt_tstr_query_t *query)
|
||||||
|
{
|
||||||
|
#if (NXT_HAVE_NJS)
|
||||||
|
nxt_js_release(&query->cache->js);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ nxt_tstr_t *nxt_tstr_compile(nxt_tstr_state_t *state, nxt_str_t *str,
|
|||||||
nxt_tstr_flags_t flags);
|
nxt_tstr_flags_t flags);
|
||||||
nxt_int_t nxt_tstr_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error);
|
nxt_int_t nxt_tstr_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error);
|
||||||
nxt_int_t nxt_tstr_state_done(nxt_tstr_state_t *state, u_char *error);
|
nxt_int_t nxt_tstr_state_done(nxt_tstr_state_t *state, u_char *error);
|
||||||
|
void nxt_tstr_state_release(nxt_tstr_state_t *state);
|
||||||
|
|
||||||
nxt_bool_t nxt_tstr_is_const(nxt_tstr_t *tstr);
|
nxt_bool_t nxt_tstr_is_const(nxt_tstr_t *tstr);
|
||||||
void nxt_tstr_str(nxt_tstr_t *tstr, nxt_str_t *str);
|
void nxt_tstr_str(nxt_tstr_t *tstr, nxt_str_t *str);
|
||||||
@@ -55,6 +56,7 @@ void nxt_tstr_query_resolve(nxt_task_t *task, nxt_tstr_query_t *query,
|
|||||||
void *data, nxt_work_handler_t ready, nxt_work_handler_t error);
|
void *data, nxt_work_handler_t ready, nxt_work_handler_t error);
|
||||||
void nxt_tstr_query_handle(nxt_task_t *task, nxt_tstr_query_t *query,
|
void nxt_tstr_query_handle(nxt_task_t *task, nxt_tstr_query_t *query,
|
||||||
nxt_bool_t failed);
|
nxt_bool_t failed);
|
||||||
|
void nxt_tstr_query_release(nxt_tstr_query_t *query);
|
||||||
|
|
||||||
|
|
||||||
nxt_inline nxt_bool_t
|
nxt_inline nxt_bool_t
|
||||||
|
|||||||
Reference in New Issue
Block a user