mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
- Fix #775: libunbound: subprocess reap causes parent process reap
to hang.
This commit is contained in:
parent
52a9e6268e
commit
dda1d9544c
5 changed files with 46 additions and 1 deletions
|
|
@ -1,6 +1,8 @@
|
|||
8 November 2022: Wouter
|
||||
- Fix to ignore tcp events for closed comm points.
|
||||
- Fix to make sure to not read again after a tcp comm point is closed.
|
||||
- Fix #775: libunbound: subprocess reap causes parent process reap
|
||||
to hang.
|
||||
|
||||
21 October 2022: George
|
||||
- Merge #767 from jonathangray: consistently use IPv4/IPv6 in
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ context_finalize(struct ub_ctx* ctx)
|
|||
} else {
|
||||
log_init(cfg->logfile, cfg->use_syslog, NULL);
|
||||
}
|
||||
ctx->pipe_pid = getpid();
|
||||
cfg_apply_local_port_policy(cfg, 65536);
|
||||
config_apply(cfg);
|
||||
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
|
|
|
|||
|
|
@ -89,6 +89,12 @@ struct ub_ctx {
|
|||
pid_t bg_pid;
|
||||
/** tid of bg worker thread */
|
||||
ub_thread_type bg_tid;
|
||||
/** pid when pipes are created. This was the process when the
|
||||
* setup was called. Helps with clean up, so we can tell after a fork
|
||||
* which side of the fork the delete is on. */
|
||||
pid_t pipe_pid;
|
||||
/** when threaded, the worker that exists in the created thread. */
|
||||
struct libworker* thread_worker;
|
||||
|
||||
/** do threading (instead of forking) for async resolution */
|
||||
int dothread;
|
||||
|
|
|
|||
|
|
@ -305,11 +305,29 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
|||
int do_stop = 1;
|
||||
if(!ctx) return;
|
||||
|
||||
/* if the delete is called but it has forked, and before the fork
|
||||
* the context was finalized, then the bg worker is not stopped
|
||||
* from here. There is one worker, but two contexts that refer to
|
||||
* it and only one should clean up, the one with getpid == pipe_pid.*/
|
||||
if(ctx->created_bg && ctx->pipe_pid != getpid()) {
|
||||
do_stop = 0;
|
||||
/* Stop events from getting deregistered, if the backend is
|
||||
* epoll, the epoll fd is the same as the other process.
|
||||
* That process should deregister them. */
|
||||
if(ctx->qq_pipe->listen_com)
|
||||
ctx->qq_pipe->listen_com->event_added = 0;
|
||||
if(ctx->qq_pipe->res_com)
|
||||
ctx->qq_pipe->res_com->event_added = 0;
|
||||
if(ctx->rr_pipe->listen_com)
|
||||
ctx->rr_pipe->listen_com->event_added = 0;
|
||||
if(ctx->rr_pipe->res_com)
|
||||
ctx->rr_pipe->res_com->event_added = 0;
|
||||
}
|
||||
/* see if bg thread is created and if threads have been killed */
|
||||
/* no locks, because those may be held by terminated threads */
|
||||
/* for processes the read pipe is closed and we see that on read */
|
||||
#ifdef HAVE_PTHREAD
|
||||
if(ctx->created_bg && ctx->dothread) {
|
||||
if(ctx->created_bg && ctx->dothread && do_stop) {
|
||||
if(pthread_kill(ctx->bg_tid, 0) == ESRCH) {
|
||||
/* thread has been killed */
|
||||
do_stop = 0;
|
||||
|
|
@ -318,6 +336,23 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
|||
#endif /* HAVE_PTHREAD */
|
||||
if(do_stop)
|
||||
ub_stop_bg(ctx);
|
||||
if(ctx->created_bg && ctx->pipe_pid != getpid() && ctx->thread_worker) {
|
||||
/* This delete is happening from a different process. Delete
|
||||
* the thread worker from this process memory space. The
|
||||
* thread is not there to do so, so it is freed here. */
|
||||
struct ub_event_base* evbase = comm_base_internal(
|
||||
ctx->thread_worker->base);
|
||||
libworker_delete_event(ctx->thread_worker);
|
||||
ctx->thread_worker = NULL;
|
||||
#ifdef USE_MINI_EVENT
|
||||
ub_event_base_free(evbase);
|
||||
#else
|
||||
/* cannot event_base_free, because the epoll_fd cleanup
|
||||
* in libevent could stop the original event_base in the
|
||||
* other process from working. */
|
||||
free(evbase);
|
||||
#endif
|
||||
}
|
||||
libworker_delete_event(ctx->event_worker);
|
||||
|
||||
modstack_desetup(&ctx->mods, ctx->env);
|
||||
|
|
|
|||
|
|
@ -395,6 +395,7 @@ int libworker_bg(struct ub_ctx* ctx)
|
|||
w = libworker_setup(ctx, 1, NULL);
|
||||
if(!w) return UB_NOMEM;
|
||||
w->is_bg_thread = 1;
|
||||
ctx->thread_worker = w;
|
||||
#ifdef ENABLE_LOCK_CHECKS
|
||||
w->thread_num = 1; /* for nicer DEBUG checklocks */
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue