Signal solution

git-svn-id: file:///svn/unbound/trunk@152 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-02-27 10:33:04 +00:00
parent 78d01c6f48
commit 0e3a023540
7 changed files with 78 additions and 8 deletions

View file

@ -48,11 +48,61 @@
#include "util/log.h"
#include "util/config_file.h"
#include "services/listen_dnsport.h"
/* @@@ TODO remove */
#include "pthread.h"
#include <signal.h>
/** How many quit requests happened. */
static int sig_record_quit = 0;
/** How many reload requests happened. */
static int sig_record_reload = 0;
/** used when no other sighandling happens, so we don't die
* when multiple signals in quick succession are sent to us. */
static RETSIGTYPE record_sigh(int sig)
{
switch(sig)
{
case SIGTERM:
case SIGQUIT:
case SIGINT:
sig_record_quit++;
break;
case SIGHUP:
sig_record_reload++;
break;
default:
log_err("ignoring signal %d", sig);
}
}
/**
* Signal handling during the time when netevent is disabled.
* Stores signals to replay later.
*/
static void
signal_handling_record()
{
if( signal(SIGTERM, record_sigh) == SIG_ERR ||
signal(SIGQUIT, record_sigh) == SIG_ERR ||
signal(SIGINT, record_sigh) == SIG_ERR ||
signal(SIGHUP, record_sigh) == SIG_ERR)
log_err("install sighandler: %s", strerror(errno));
}
/**
* Replay old signals.
* @param wrk: worker that handles signals.
*/
static void
signal_handling_playback(struct worker* wrk)
{
if(sig_record_quit)
worker_sighandler(SIGTERM, wrk);
if(sig_record_reload)
worker_sighandler(SIGHUP, wrk);
sig_record_quit = 0;
sig_record_reload = 0;
}
struct daemon*
daemon_init()
{
@ -60,6 +110,7 @@ daemon_init()
sizeof(struct daemon));
if(!daemon)
return NULL;
signal_handling_record();
lock_basic_init(&daemon->lock);
daemon->need_to_exit = 0;
return daemon;
@ -212,7 +263,7 @@ daemon_fork(struct daemon* daemon)
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports,
BUFSZ, 1))
fatal_exit("Could not initialize main thread");
/* see if other threads have started correctly? */
signal_handling_playback(daemon->workers[0]);
/* Start resolver service on main thread. */
log_info("start of service (%s).", PACKAGE_STRING);
@ -231,6 +282,9 @@ daemon_cleanup(struct daemon* daemon)
{
int i;
log_assert(daemon);
/* before stopping main worker, handle signals ourselves, so we
don't die on multiple reload signals for example. */
signal_handling_record();
for(i=0; i<daemon->num; i++)
worker_delete(daemon->workers[i]);
free(daemon->workers);

View file

@ -101,7 +101,8 @@ void daemon_fork(struct daemon* daemon);
void daemon_cleanup(struct daemon* daemon);
/**
* Delete worker.
* Delete workers, close listening ports.
* @param daemon: the daemon.
*/
void daemon_delete(struct daemon* daemon);

View file

@ -376,15 +376,18 @@ worker_delete(struct worker* worker)
{
if(!worker)
return;
close(worker->cmd_send_fd);
if(worker->cmd_send_fd != -1)
close(worker->cmd_send_fd);
worker->cmd_send_fd = -1;
close(worker->cmd_recv_fd);
if(worker->cmd_recv_fd != -1)
close(worker->cmd_recv_fd);
worker->cmd_recv_fd = -1;
listen_delete(worker->front);
outside_network_delete(worker->back);
comm_signal_delete(worker->comsig);
comm_point_delete(worker->cmd_com);
comm_base_delete(worker->base);
ub_randfree(worker->rndstate);
free(worker->rndstate);
free(worker);
}

View file

@ -157,4 +157,11 @@ int worker_set_fwd(struct worker* worker, const char* ip, int port);
void worker_send_cmd(struct worker* worker, ldns_buffer* buffer,
enum worker_commands cmd);
/**
* Worker signal handler function. User argument is the worker itself.
* @param sig: signal number.
* @param arg: the worker (main worker) that handles signals.
*/
void worker_sighandler(int sig, void* arg);
#endif /* DAEMON_WORKER_H */

View file

@ -3,6 +3,8 @@
- forking is used if no threading is available.
Tested, it works, since pipes work across processes as well.
Thread_join is replaced with waitpid.
- During reloads the daemon will temporarily handle signals,
so that they do not result in problems.
26 February 2007: Wouter
- ub_random code used to select ID and port.

View file

@ -507,7 +507,8 @@ static void comm_point_local_handle_callback(int fd, short event, void* arg)
if(event&EV_READ) {
if(!comm_point_tcp_handle_read(fd, c, 1)) {
log_err("error in localhdl");
(void)(*c->callback)(c, c->cb_arg, NETEVENT_CLOSED,
NULL);
}
return;
}

View file

@ -357,5 +357,7 @@ ub_random (struct ub_randstate* s)
void ub_randfree(struct ub_randstate* state)
{
if(!state)
return;
free(state->state);
}