app.c revision e8336c458cca9289f34dc5cb58fc0b5769502649
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington/*
431a83fb29482c5170b3e4026e59bb14849a6707Tinderbox User * Copyright (C) 1999, 2000 Internet Software Consortium.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews *
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington * Permission to use, copy, modify, and distribute this software for any
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * purpose with or without fee is hereby granted, provided that the above
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington * copyright notice and this permission notice appear in all copies.
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington *
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * SOFTWARE.
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington */
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington
328e0fee6b6c91c258e5ce36eb70f5e017a85af2Mark Andrews#include <config.h>
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#include <pthread.h>
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#include <sys/types.h>
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#include <stddef.h>
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#include <errno.h>
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#include <unistd.h>
368aedf188d7c7782cae8a5ce2a978be47b5a764Evan Hunt#include <signal.h>
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
5cd7e9d4db393c314dd1a761c52d2cb3a4da9b72Andreas Gustafsson#include <isc/app.h>
7332e47e11ceb87928f801b925269aa6a91838b1David Lawrence#include <isc/boolean.h>
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews#include <isc/mutex.h>
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#include <isc/event.h>
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#include <isc/string.h>
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#include <isc/task.h>
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#include <isc/util.h>
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonstatic isc_eventlist_t on_run;
669e9657c731176df235832367f61435f7b83ddfAndreas Gustafssonstatic isc_mutex_t lock;
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrewsstatic isc_boolean_t shutdown_requested = ISC_FALSE;
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrewsstatic isc_boolean_t running = ISC_FALSE;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington/*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * We assume that 'want_shutdown' can be read and written atomically.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonstatic isc_boolean_t want_shutdown = ISC_FALSE;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington/*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * We assume that 'want_reload' can be read and written atomically.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrewsstatic isc_boolean_t want_reload = ISC_FALSE;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#ifdef HAVE_LINUXTHREADS
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington/*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * Linux has sigwait(), but it appears to prevent signal handlers from
3dfc806ddf433d0569340d9c4ccc5af8ec41a27bBrian Wellington * running, even if they're not in the set being waited for. This makes
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * it impossible to get the default actions for SIGILL, SIGSEGV, etc.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * Instead of messing with it, we just use sigsuspend() instead.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#undef HAVE_SIGWAIT
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington/*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * We need to remember which thread is the main thread...
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonstatic pthread_t main_thread;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#endif
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#ifndef HAVE_SIGWAIT
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonstatic void
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonexit_action(int arg) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington UNUSED(arg);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington want_shutdown = ISC_TRUE;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington}
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonstatic void
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonreload_action(int arg) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington UNUSED(arg);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington want_reload = ISC_TRUE;
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt}
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#endif
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonstatic isc_result_t
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonhandle_signal(int sig, void (*handler)(int)) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington struct sigaction sa;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington memset(&sa, 0, sizeof sa);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington sa.sa_handler = handler;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (sigfillset(&sa.sa_mask) != 0 ||
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington sigaction(sig, &sa, NULL) < 0) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington UNEXPECTED_ERROR(__FILE__, __LINE__,
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews "handle_signal() %d setup: %s", sig,
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington strerror(errno));
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington return (ISC_R_UNEXPECTED);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington }
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
532989b206894bdaf6de6cb883d2e31169c4bfacAndreas Gustafsson return (ISC_R_SUCCESS);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington}
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonisc_result_t
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonisc_app_start(void) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington isc_result_t result;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington int presult;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington sigset_t sset;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington /*
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews * Start an ISC library application.
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews */
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews#ifdef NEED_PTHREAD_INIT
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington /*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * BSDI 3.1 seg faults in pthread_sigmask() if we don't do this.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
532989b206894bdaf6de6cb883d2e31169c4bfacAndreas Gustafsson presult = pthread_init();
532989b206894bdaf6de6cb883d2e31169c4bfacAndreas Gustafsson if (presult != 0) {
532989b206894bdaf6de6cb883d2e31169c4bfacAndreas Gustafsson UNEXPECTED_ERROR(__FILE__, __LINE__,
b32e75f3e1822f14681c538d7657bdbccd7fcd45Brian Wellington "isc_app_start() pthread_init: %s",
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews strerror(presult));
532989b206894bdaf6de6cb883d2e31169c4bfacAndreas Gustafsson return (ISC_R_UNEXPECTED);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington }
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#endif
091329e690b20755aa80b86cc7389d25c5d32c9bBrian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#ifdef HAVE_LINUXTHREADS
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews main_thread = pthread_self();
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews#endif
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington result = isc_mutex_init(&lock);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (result != ISC_R_SUCCESS)
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington return (result);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#ifndef HAVE_SIGWAIT
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington /*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * Install do-nothing handlers for SIGINT and SIGTERM.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington *
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * We install them now because BSDI 3.1 won't block
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * the default actions, regardless of what we do with
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * pthread_sigmask().
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington result = handle_signal(SIGINT, exit_action);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (result != ISC_R_SUCCESS)
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington return (result);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington result = handle_signal(SIGTERM, exit_action);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (result != ISC_R_SUCCESS)
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington return (result);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#endif
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington /*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * Always ignore SIGPIPE.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington result = handle_signal(SIGPIPE, SIG_IGN);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (result != ISC_R_SUCCESS)
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington return (result);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington /*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * Block SIGHUP, SIGINT, SIGTERM.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington *
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * If isc_app_start() is called from the main thread before any other
3a0da183bb40bd120698102b20b61ef12665c09bMark Andrews * threads have been created, then the pthread_sigmask() call below
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * will result in all threads having SIGHUP, SIGINT and SIGTERM
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * blocked by default, ensuring that only the thread that calls
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * sigwait() for them will get those signals.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (sigemptyset(&sset) != 0 ||
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington sigaddset(&sset, SIGHUP) != 0 ||
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington sigaddset(&sset, SIGINT) != 0 ||
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington sigaddset(&sset, SIGTERM) != 0) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington UNEXPECTED_ERROR(__FILE__, __LINE__,
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington "isc_app_start() sigsetops: %s",
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington strerror(errno));
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington return (ISC_R_UNEXPECTED);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington }
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington presult = pthread_sigmask(SIG_BLOCK, &sset, NULL);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (presult != 0) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington UNEXPECTED_ERROR(__FILE__, __LINE__,
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington "isc_app_start() pthread_sigmask: %s",
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington strerror(presult));
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington return (ISC_R_UNEXPECTED);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington }
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington ISC_LIST_INIT(on_run);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington return (ISC_R_SUCCESS);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington}
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonisc_result_t
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonisc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington void *arg)
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington{
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington isc_event_t *event;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington isc_task_t *cloned_task = NULL;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington isc_result_t result;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
32d248107a5bc92b4bf9fc77deaa55b3da969ba2Andreas Gustafsson /*
32d248107a5bc92b4bf9fc77deaa55b3da969ba2Andreas Gustafsson * Request delivery of an event when the application is run.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
ed3418751ebdf7de397df76753dae97851d2bdf9Brian Wellington
ed3418751ebdf7de397df76753dae97851d2bdf9Brian Wellington LOCK(&lock);
ed3418751ebdf7de397df76753dae97851d2bdf9Brian Wellington
32d248107a5bc92b4bf9fc77deaa55b3da969ba2Andreas Gustafsson if (running) {
32d248107a5bc92b4bf9fc77deaa55b3da969ba2Andreas Gustafsson result = ISC_R_ALREADYRUNNING;
ed3418751ebdf7de397df76753dae97851d2bdf9Brian Wellington goto unlock;
ed3418751ebdf7de397df76753dae97851d2bdf9Brian Wellington }
ed3418751ebdf7de397df76753dae97851d2bdf9Brian Wellington
ed3418751ebdf7de397df76753dae97851d2bdf9Brian Wellington /*
ed3418751ebdf7de397df76753dae97851d2bdf9Brian Wellington * Note that we store the task to which we're going to send the event
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews * in the event's "sender" field.
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews */
ed3418751ebdf7de397df76753dae97851d2bdf9Brian Wellington isc_task_attach(task, &cloned_task);
ed3418751ebdf7de397df76753dae97851d2bdf9Brian Wellington event = isc_event_allocate(mctx, cloned_task, ISC_APPEVENT_SHUTDOWN,
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington action, arg, sizeof *event);
32d248107a5bc92b4bf9fc77deaa55b3da969ba2Andreas Gustafsson if (event == NULL) {
32d248107a5bc92b4bf9fc77deaa55b3da969ba2Andreas Gustafsson result = ISC_R_NOMEMORY;
32d248107a5bc92b4bf9fc77deaa55b3da969ba2Andreas Gustafsson goto unlock;
32d248107a5bc92b4bf9fc77deaa55b3da969ba2Andreas Gustafsson }
32d248107a5bc92b4bf9fc77deaa55b3da969ba2Andreas Gustafsson
32d248107a5bc92b4bf9fc77deaa55b3da969ba2Andreas Gustafsson ISC_LIST_APPEND(on_run, event, ev_link);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington result = ISC_R_SUCCESS;
32d248107a5bc92b4bf9fc77deaa55b3da969ba2Andreas Gustafsson
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington unlock:
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington UNLOCK(&lock);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
32d248107a5bc92b4bf9fc77deaa55b3da969ba2Andreas Gustafsson return (result);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington}
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonisc_result_t
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonisc_app_run(void) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington int result;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington sigset_t sset;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington isc_event_t *event, *next_event;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington isc_task_t *task;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#ifdef HAVE_SIGWAIT
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington int sig;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#endif
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington /*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * Run an ISC library application.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#ifdef HAVE_LINUXTHREADS
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington REQUIRE(main_thread == pthread_self());
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#endif
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington LOCK(&lock);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (!running) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington running = ISC_TRUE;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington /*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * Post any on-run events (in FIFO order).
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington for (event = ISC_LIST_HEAD(on_run);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington event != NULL;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington event = next_event) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington next_event = ISC_LIST_NEXT(event, ev_link);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington ISC_LIST_UNLINK(on_run, event, ev_link);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington task = event->ev_sender;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington event->ev_sender = (void *)&running;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington isc_task_sendanddetach(&task, &event);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington }
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington }
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington UNLOCK(&lock);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#ifndef HAVE_SIGWAIT
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington /*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * Catch SIGHUP.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington *
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * We do this here to ensure that the signal handler is installed
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * (i.e. that it wasn't a "one-shot" handler).
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington result = handle_signal(SIGHUP, reload_action);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (result != ISC_R_SUCCESS)
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington return (ISC_R_SUCCESS);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#endif
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington /*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * There is no danger if isc_app_shutdown() is called before we wait
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * for signals. Signals are blocked, so any such signal will simply
091329e690b20755aa80b86cc7389d25c5d32c9bBrian Wellington * be made pending and we will get it when we call sigwait().
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington while (!want_shutdown) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#ifdef HAVE_SIGWAIT
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington /*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * Wait for SIGHUP, SIGINT, or SIGTERM.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (sigemptyset(&sset) != 0 ||
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington sigaddset(&sset, SIGHUP) != 0 ||
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington sigaddset(&sset, SIGINT) != 0 ||
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington sigaddset(&sset, SIGTERM) != 0) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington UNEXPECTED_ERROR(__FILE__, __LINE__,
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington "isc_app_run() sigsetops: %s",
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington strerror(errno));
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington return (ISC_R_UNEXPECTED);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington }
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#ifndef HAVE_UNIXWARE_SIGWAIT
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington result = sigwait(&sset, &sig);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (result == 0) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (sig == SIGINT ||
091329e690b20755aa80b86cc7389d25c5d32c9bBrian Wellington sig == SIGTERM)
091329e690b20755aa80b86cc7389d25c5d32c9bBrian Wellington want_shutdown = ISC_TRUE;
091329e690b20755aa80b86cc7389d25c5d32c9bBrian Wellington else if (sig == SIGHUP)
091329e690b20755aa80b86cc7389d25c5d32c9bBrian Wellington want_reload = ISC_TRUE;
091329e690b20755aa80b86cc7389d25c5d32c9bBrian Wellington }
091329e690b20755aa80b86cc7389d25c5d32c9bBrian Wellington
091329e690b20755aa80b86cc7389d25c5d32c9bBrian Wellington#else /* Using UnixWare sigwait semantics. */
091329e690b20755aa80b86cc7389d25c5d32c9bBrian Wellington sig = sigwait(&sset);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (sig >= 0) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (sig == SIGINT ||
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington sig == SIGTERM)
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington want_shutdown = ISC_TRUE;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington else if (sig == SIGHUP)
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington want_reload = ISC_TRUE;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington }
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#endif /* HAVE_UNIXWARE_SIGWAIT */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#else /* Don't have sigwait(). */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington /*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * Listen for all signals.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (sigemptyset(&sset) != 0) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington UNEXPECTED_ERROR(__FILE__, __LINE__,
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington "isc_app_run() sigsetops: %s",
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington strerror(errno));
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington return (ISC_R_UNEXPECTED);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington }
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington result = sigsuspend(&sset);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington#endif /* HAVE_SIGWAIT */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (want_reload) {
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt want_reload = ISC_FALSE;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington return (ISC_R_RELOAD);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington }
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington }
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington return (ISC_R_SUCCESS);
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington}
2c2be89824d3899591d34c26adb155da6a993ce3Evan Hunt
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonisc_result_t
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellingtonisc_app_shutdown(void) {
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews isc_boolean_t want_kill = ISC_TRUE;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews /*
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews * Request application shutdown.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington LOCK(&lock);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington REQUIRE(running);
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington if (shutdown_requested)
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington want_kill = ISC_FALSE;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater else
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater shutdown_requested = ISC_TRUE;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater
640923da589bc5b8492ac407ef89ea1ee9a1c358Andreas Gustafsson UNLOCK(&lock);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
091329e690b20755aa80b86cc7389d25c5d32c9bBrian Wellington if (want_kill) {
091329e690b20755aa80b86cc7389d25c5d32c9bBrian Wellington#ifdef HAVE_LINUXTHREADS
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington int result;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington result = pthread_kill(main_thread, SIGTERM);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington if (result != 0) {
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington UNEXPECTED_ERROR(__FILE__, __LINE__,
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington "isc_app_shutdown() pthread_kill: %s",
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington strerror(result));
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington return (ISC_R_UNEXPECTED);
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington }
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington#else
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington if (kill(getpid(), SIGTERM) < 0) {
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington UNEXPECTED_ERROR(__FILE__, __LINE__,
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington "isc_app_shutdown() kill: %s",
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington strerror(errno));
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington return (ISC_R_UNEXPECTED);
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt }
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington#endif
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt }
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt return (ISC_R_SUCCESS);
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington}
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington
546c2bf791782df1077217bdaf1865235fa95a93Mark Andrewsisc_result_t
c298583db573a329f37d43301d8c3c812500ac85Mark Andrewsisc_app_reload(void) {
c298583db573a329f37d43301d8c3c812500ac85Mark Andrews isc_boolean_t want_kill = ISC_TRUE;
c298583db573a329f37d43301d8c3c812500ac85Mark Andrews
c298583db573a329f37d43301d8c3c812500ac85Mark Andrews /*
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington * Request application reload.
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington */
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington
c2da4f9d8a153ffeb2b659541130abef2d586789Brian Wellington LOCK(&lock);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington REQUIRE(running);
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington /*
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington * Don't send the reload signal if we're shutting down.
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington */
546c2bf791782df1077217bdaf1865235fa95a93Mark Andrews if (shutdown_requested)
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington want_kill = ISC_FALSE;
1b4e6163bed546ca7f8ad186f3eabfebacc36bc1Brian Wellington
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews UNLOCK(&lock);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews if (want_kill) {
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews#ifdef HAVE_LINUXTHREADS
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews int result;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews result = pthread_kill(main_thread, SIGHUP);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews if (result != 0) {
546c2bf791782df1077217bdaf1865235fa95a93Mark Andrews UNEXPECTED_ERROR(__FILE__, __LINE__,
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews "isc_app_shutdown() pthread_kill: %s",
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews strerror(result));
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews return (ISC_R_UNEXPECTED);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews }
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews#else
546c2bf791782df1077217bdaf1865235fa95a93Mark Andrews if (kill(getpid(), SIGHUP) < 0) {
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews UNEXPECTED_ERROR(__FILE__, __LINE__,
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews "isc_app_shutdown() kill: %s",
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews strerror(errno));
546c2bf791782df1077217bdaf1865235fa95a93Mark Andrews return (ISC_R_UNEXPECTED);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews }
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews#endif
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews }
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews return (ISC_R_SUCCESS);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews}
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrewsvoid
546c2bf791782df1077217bdaf1865235fa95a93Mark Andrewsisc_app_finish(void) {
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews /*
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews * Finish an ISC library application.
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews */
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews (void)isc_mutex_destroy(&lock);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews}
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews