Annotation of embedaddon/ntp/lib/isc/unix/app.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
! 3: * Copyright (C) 1999-2003 Internet Software Consortium.
! 4: *
! 5: * Permission to use, copy, modify, and/or distribute this software for any
! 6: * purpose with or without fee is hereby granted, provided that the above
! 7: * copyright notice and this permission notice appear in all copies.
! 8: *
! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
! 10: * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
! 11: * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
! 12: * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
! 13: * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
! 14: * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
! 15: * PERFORMANCE OF THIS SOFTWARE.
! 16: */
! 17:
! 18: /* $Id: app.c,v 1.60 2008/10/15 03:41:17 marka Exp $ */
! 19:
! 20: /*! \file */
! 21:
! 22: #include <config.h>
! 23:
! 24: #include <sys/param.h> /* Openserver 5.0.6A and FD_SETSIZE */
! 25: #include <sys/types.h>
! 26:
! 27: #include <stddef.h>
! 28: #include <stdlib.h>
! 29: #include <errno.h>
! 30: #include <unistd.h>
! 31: #include <signal.h>
! 32: #include <sys/time.h>
! 33: #ifdef HAVE_EPOLL
! 34: #include <sys/epoll.h>
! 35: #endif
! 36:
! 37: #include <isc/app.h>
! 38: #include <isc/boolean.h>
! 39: #include <isc/condition.h>
! 40: #include <isc/msgs.h>
! 41: #include <isc/mutex.h>
! 42: #include <isc/event.h>
! 43: #include <isc/platform.h>
! 44: #include <isc/strerror.h>
! 45: #include <isc/string.h>
! 46: #include <isc/task.h>
! 47: #include <isc/time.h>
! 48: #include <isc/util.h>
! 49:
! 50: #ifdef ISC_PLATFORM_USETHREADS
! 51: #include <pthread.h>
! 52: #else /* ISC_PLATFORM_USETHREADS */
! 53: #include "../timer_p.h"
! 54: #include "../task_p.h"
! 55: #include "socket_p.h"
! 56: #endif /* ISC_PLATFORM_USETHREADS */
! 57:
! 58: static isc_eventlist_t on_run;
! 59: static isc_mutex_t lock;
! 60: static isc_boolean_t shutdown_requested = ISC_FALSE;
! 61: static isc_boolean_t running = ISC_FALSE;
! 62: /*!
! 63: * We assume that 'want_shutdown' can be read and written atomically.
! 64: */
! 65: static volatile isc_boolean_t want_shutdown = ISC_FALSE;
! 66: /*
! 67: * We assume that 'want_reload' can be read and written atomically.
! 68: */
! 69: static volatile isc_boolean_t want_reload = ISC_FALSE;
! 70:
! 71: static isc_boolean_t blocked = ISC_FALSE;
! 72: #ifdef ISC_PLATFORM_USETHREADS
! 73: static pthread_t blockedthread;
! 74: #endif /* ISC_PLATFORM_USETHREADS */
! 75:
! 76: #ifdef HAVE_LINUXTHREADS
! 77: /*!
! 78: * Linux has sigwait(), but it appears to prevent signal handlers from
! 79: * running, even if they're not in the set being waited for. This makes
! 80: * it impossible to get the default actions for SIGILL, SIGSEGV, etc.
! 81: * Instead of messing with it, we just use sigsuspend() instead.
! 82: */
! 83: #undef HAVE_SIGWAIT
! 84: /*!
! 85: * We need to remember which thread is the main thread...
! 86: */
! 87: static pthread_t main_thread;
! 88: #endif
! 89:
! 90: #ifndef HAVE_SIGWAIT
! 91: static void
! 92: exit_action(int arg) {
! 93: UNUSED(arg);
! 94: want_shutdown = ISC_TRUE;
! 95: }
! 96:
! 97: static void
! 98: reload_action(int arg) {
! 99: UNUSED(arg);
! 100: want_reload = ISC_TRUE;
! 101: }
! 102: #endif
! 103:
! 104: static isc_result_t
! 105: handle_signal(int sig, void (*handler)(int)) {
! 106: struct sigaction sa;
! 107: char strbuf[ISC_STRERRORSIZE];
! 108:
! 109: memset(&sa, 0, sizeof(sa));
! 110: sa.sa_handler = handler;
! 111:
! 112: if (sigfillset(&sa.sa_mask) != 0 ||
! 113: sigaction(sig, &sa, NULL) < 0) {
! 114: isc__strerror(errno, strbuf, sizeof(strbuf));
! 115: UNEXPECTED_ERROR(__FILE__, __LINE__,
! 116: isc_msgcat_get(isc_msgcat, ISC_MSGSET_APP,
! 117: ISC_MSG_SIGNALSETUP,
! 118: "handle_signal() %d setup: %s"),
! 119: sig, strbuf);
! 120: return (ISC_R_UNEXPECTED);
! 121: }
! 122:
! 123: return (ISC_R_SUCCESS);
! 124: }
! 125:
! 126: isc_result_t
! 127: isc_app_start(void) {
! 128: isc_result_t result;
! 129: int presult;
! 130: sigset_t sset;
! 131: char strbuf[ISC_STRERRORSIZE];
! 132:
! 133: /*
! 134: * Start an ISC library application.
! 135: */
! 136:
! 137: #ifdef NEED_PTHREAD_INIT
! 138: /*
! 139: * BSDI 3.1 seg faults in pthread_sigmask() if we don't do this.
! 140: */
! 141: presult = pthread_init();
! 142: if (presult != 0) {
! 143: isc__strerror(presult, strbuf, sizeof(strbuf));
! 144: UNEXPECTED_ERROR(__FILE__, __LINE__,
! 145: "isc_app_start() pthread_init: %s", strbuf);
! 146: return (ISC_R_UNEXPECTED);
! 147: }
! 148: #endif
! 149:
! 150: #ifdef HAVE_LINUXTHREADS
! 151: main_thread = pthread_self();
! 152: #endif
! 153:
! 154: result = isc_mutex_init(&lock);
! 155: if (result != ISC_R_SUCCESS)
! 156: return (result);
! 157:
! 158: #ifndef HAVE_SIGWAIT
! 159: /*
! 160: * Install do-nothing handlers for SIGINT and SIGTERM.
! 161: *
! 162: * We install them now because BSDI 3.1 won't block
! 163: * the default actions, regardless of what we do with
! 164: * pthread_sigmask().
! 165: */
! 166: result = handle_signal(SIGINT, exit_action);
! 167: if (result != ISC_R_SUCCESS)
! 168: return (result);
! 169: result = handle_signal(SIGTERM, exit_action);
! 170: if (result != ISC_R_SUCCESS)
! 171: return (result);
! 172: #endif
! 173:
! 174: /*
! 175: * Always ignore SIGPIPE.
! 176: */
! 177: result = handle_signal(SIGPIPE, SIG_IGN);
! 178: if (result != ISC_R_SUCCESS)
! 179: return (result);
! 180:
! 181: /*
! 182: * On Solaris 2, delivery of a signal whose action is SIG_IGN
! 183: * will not cause sigwait() to return. We may have inherited
! 184: * unexpected actions for SIGHUP, SIGINT, and SIGTERM from our parent
! 185: * process (e.g, Solaris cron). Set an action of SIG_DFL to make
! 186: * sure sigwait() works as expected. Only do this for SIGTERM and
! 187: * SIGINT if we don't have sigwait(), since a different handler is
! 188: * installed above.
! 189: */
! 190: result = handle_signal(SIGHUP, SIG_DFL);
! 191: if (result != ISC_R_SUCCESS)
! 192: return (result);
! 193:
! 194: #ifdef HAVE_SIGWAIT
! 195: result = handle_signal(SIGTERM, SIG_DFL);
! 196: if (result != ISC_R_SUCCESS)
! 197: return (result);
! 198: result = handle_signal(SIGINT, SIG_DFL);
! 199: if (result != ISC_R_SUCCESS)
! 200: return (result);
! 201: #endif
! 202:
! 203: #ifdef ISC_PLATFORM_USETHREADS
! 204: /*
! 205: * Block SIGHUP, SIGINT, SIGTERM.
! 206: *
! 207: * If isc_app_start() is called from the main thread before any other
! 208: * threads have been created, then the pthread_sigmask() call below
! 209: * will result in all threads having SIGHUP, SIGINT and SIGTERM
! 210: * blocked by default, ensuring that only the thread that calls
! 211: * sigwait() for them will get those signals.
! 212: */
! 213: if (sigemptyset(&sset) != 0 ||
! 214: sigaddset(&sset, SIGHUP) != 0 ||
! 215: sigaddset(&sset, SIGINT) != 0 ||
! 216: sigaddset(&sset, SIGTERM) != 0) {
! 217: isc__strerror(errno, strbuf, sizeof(strbuf));
! 218: UNEXPECTED_ERROR(__FILE__, __LINE__,
! 219: "isc_app_start() sigsetops: %s", strbuf);
! 220: return (ISC_R_UNEXPECTED);
! 221: }
! 222: presult = pthread_sigmask(SIG_BLOCK, &sset, NULL);
! 223: if (presult != 0) {
! 224: isc__strerror(presult, strbuf, sizeof(strbuf));
! 225: UNEXPECTED_ERROR(__FILE__, __LINE__,
! 226: "isc_app_start() pthread_sigmask: %s",
! 227: strbuf);
! 228: return (ISC_R_UNEXPECTED);
! 229: }
! 230: #else /* ISC_PLATFORM_USETHREADS */
! 231: /*
! 232: * Unblock SIGHUP, SIGINT, SIGTERM.
! 233: *
! 234: * If we're not using threads, we need to make sure that SIGHUP,
! 235: * SIGINT and SIGTERM are not inherited as blocked from the parent
! 236: * process.
! 237: */
! 238: if (sigemptyset(&sset) != 0 ||
! 239: sigaddset(&sset, SIGHUP) != 0 ||
! 240: sigaddset(&sset, SIGINT) != 0 ||
! 241: sigaddset(&sset, SIGTERM) != 0) {
! 242: isc__strerror(errno, strbuf, sizeof(strbuf));
! 243: UNEXPECTED_ERROR(__FILE__, __LINE__,
! 244: "isc_app_start() sigsetops: %s", strbuf);
! 245: return (ISC_R_UNEXPECTED);
! 246: }
! 247: presult = sigprocmask(SIG_UNBLOCK, &sset, NULL);
! 248: if (presult != 0) {
! 249: isc__strerror(presult, strbuf, sizeof(strbuf));
! 250: UNEXPECTED_ERROR(__FILE__, __LINE__,
! 251: "isc_app_start() sigprocmask: %s", strbuf);
! 252: return (ISC_R_UNEXPECTED);
! 253: }
! 254: #endif /* ISC_PLATFORM_USETHREADS */
! 255:
! 256: ISC_LIST_INIT(on_run);
! 257:
! 258: return (ISC_R_SUCCESS);
! 259: }
! 260:
! 261: isc_result_t
! 262: isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
! 263: void *arg)
! 264: {
! 265: isc_event_t *event;
! 266: isc_task_t *cloned_task = NULL;
! 267: isc_result_t result;
! 268:
! 269: LOCK(&lock);
! 270:
! 271: if (running) {
! 272: result = ISC_R_ALREADYRUNNING;
! 273: goto unlock;
! 274: }
! 275:
! 276: /*
! 277: * Note that we store the task to which we're going to send the event
! 278: * in the event's "sender" field.
! 279: */
! 280: isc_task_attach(task, &cloned_task);
! 281: event = isc_event_allocate(mctx, cloned_task, ISC_APPEVENT_SHUTDOWN,
! 282: action, arg, sizeof(*event));
! 283: if (event == NULL) {
! 284: result = ISC_R_NOMEMORY;
! 285: goto unlock;
! 286: }
! 287:
! 288: ISC_LIST_APPEND(on_run, event, ev_link);
! 289:
! 290: result = ISC_R_SUCCESS;
! 291:
! 292: unlock:
! 293: UNLOCK(&lock);
! 294:
! 295: return (result);
! 296: }
! 297:
! 298: #ifndef ISC_PLATFORM_USETHREADS
! 299: /*!
! 300: * Event loop for nonthreaded programs.
! 301: */
! 302: static isc_result_t
! 303: evloop(void) {
! 304: isc_result_t result;
! 305: while (!want_shutdown) {
! 306: int n;
! 307: isc_time_t when, now;
! 308: struct timeval tv, *tvp;
! 309: isc_socketwait_t *swait;
! 310: isc_boolean_t readytasks;
! 311: isc_boolean_t call_timer_dispatch = ISC_FALSE;
! 312:
! 313: readytasks = isc__taskmgr_ready();
! 314: if (readytasks) {
! 315: tv.tv_sec = 0;
! 316: tv.tv_usec = 0;
! 317: tvp = &tv;
! 318: call_timer_dispatch = ISC_TRUE;
! 319: } else {
! 320: result = isc__timermgr_nextevent(&when);
! 321: if (result != ISC_R_SUCCESS)
! 322: tvp = NULL;
! 323: else {
! 324: isc_uint64_t us;
! 325:
! 326: TIME_NOW(&now);
! 327: us = isc_time_microdiff(&when, &now);
! 328: if (us == 0)
! 329: call_timer_dispatch = ISC_TRUE;
! 330: tv.tv_sec = us / 1000000;
! 331: tv.tv_usec = us % 1000000;
! 332: tvp = &tv;
! 333: }
! 334: }
! 335:
! 336: swait = NULL;
! 337: n = isc__socketmgr_waitevents(tvp, &swait);
! 338:
! 339: if (n == 0 || call_timer_dispatch) {
! 340: /*
! 341: * We call isc__timermgr_dispatch() only when
! 342: * necessary, in order to reduce overhead. If the
! 343: * select() call indicates a timeout, we need the
! 344: * dispatch. Even if not, if we set the 0-timeout
! 345: * for the select() call, we need to check the timer
! 346: * events. In the 'readytasks' case, there may be no
! 347: * timeout event actually, but there is no other way
! 348: * to reduce the overhead.
! 349: * Note that we do not have to worry about the case
! 350: * where a new timer is inserted during the select()
! 351: * call, since this loop only runs in the non-thread
! 352: * mode.
! 353: */
! 354: isc__timermgr_dispatch();
! 355: }
! 356: if (n > 0)
! 357: (void)isc__socketmgr_dispatch(swait);
! 358: (void)isc__taskmgr_dispatch();
! 359:
! 360: if (want_reload) {
! 361: want_reload = ISC_FALSE;
! 362: return (ISC_R_RELOAD);
! 363: }
! 364: }
! 365: return (ISC_R_SUCCESS);
! 366: }
! 367:
! 368: /*
! 369: * This is a gross hack to support waiting for condition
! 370: * variables in nonthreaded programs in a limited way;
! 371: * see lib/isc/nothreads/include/isc/condition.h.
! 372: * We implement isc_condition_wait() by entering the
! 373: * event loop recursively until the want_shutdown flag
! 374: * is set by isc_condition_signal().
! 375: */
! 376:
! 377: /*!
! 378: * \brief True if we are currently executing in the recursive
! 379: * event loop.
! 380: */
! 381: static isc_boolean_t in_recursive_evloop = ISC_FALSE;
! 382:
! 383: /*!
! 384: * \brief True if we are exiting the event loop as the result of
! 385: * a call to isc_condition_signal() rather than a shutdown
! 386: * or reload.
! 387: */
! 388: static isc_boolean_t signalled = ISC_FALSE;
! 389:
! 390: isc_result_t
! 391: isc__nothread_wait_hack(isc_condition_t *cp, isc_mutex_t *mp) {
! 392: isc_result_t result;
! 393:
! 394: UNUSED(cp);
! 395: UNUSED(mp);
! 396:
! 397: INSIST(!in_recursive_evloop);
! 398: in_recursive_evloop = ISC_TRUE;
! 399:
! 400: INSIST(*mp == 1); /* Mutex must be locked on entry. */
! 401: --*mp;
! 402:
! 403: result = evloop();
! 404: if (result == ISC_R_RELOAD)
! 405: want_reload = ISC_TRUE;
! 406: if (signalled) {
! 407: want_shutdown = ISC_FALSE;
! 408: signalled = ISC_FALSE;
! 409: }
! 410:
! 411: ++*mp;
! 412: in_recursive_evloop = ISC_FALSE;
! 413: return (ISC_R_SUCCESS);
! 414: }
! 415:
! 416: isc_result_t
! 417: isc__nothread_signal_hack(isc_condition_t *cp) {
! 418:
! 419: UNUSED(cp);
! 420:
! 421: INSIST(in_recursive_evloop);
! 422:
! 423: want_shutdown = ISC_TRUE;
! 424: signalled = ISC_TRUE;
! 425: return (ISC_R_SUCCESS);
! 426: }
! 427:
! 428: #endif /* ISC_PLATFORM_USETHREADS */
! 429:
! 430: isc_result_t
! 431: isc_app_run(void) {
! 432: int result;
! 433: isc_event_t *event, *next_event;
! 434: isc_task_t *task;
! 435: #ifdef ISC_PLATFORM_USETHREADS
! 436: sigset_t sset;
! 437: char strbuf[ISC_STRERRORSIZE];
! 438: #ifdef HAVE_SIGWAIT
! 439: int sig;
! 440: #endif
! 441: #endif /* ISC_PLATFORM_USETHREADS */
! 442:
! 443: #ifdef HAVE_LINUXTHREADS
! 444: REQUIRE(main_thread == pthread_self());
! 445: #endif
! 446:
! 447: LOCK(&lock);
! 448:
! 449: if (!running) {
! 450: running = ISC_TRUE;
! 451:
! 452: /*
! 453: * Post any on-run events (in FIFO order).
! 454: */
! 455: for (event = ISC_LIST_HEAD(on_run);
! 456: event != NULL;
! 457: event = next_event) {
! 458: next_event = ISC_LIST_NEXT(event, ev_link);
! 459: ISC_LIST_UNLINK(on_run, event, ev_link);
! 460: task = event->ev_sender;
! 461: event->ev_sender = NULL;
! 462: isc_task_sendanddetach(&task, &event);
! 463: }
! 464:
! 465: }
! 466:
! 467: UNLOCK(&lock);
! 468:
! 469: #ifndef HAVE_SIGWAIT
! 470: /*
! 471: * Catch SIGHUP.
! 472: *
! 473: * We do this here to ensure that the signal handler is installed
! 474: * (i.e. that it wasn't a "one-shot" handler).
! 475: */
! 476: result = handle_signal(SIGHUP, reload_action);
! 477: if (result != ISC_R_SUCCESS)
! 478: return (ISC_R_SUCCESS);
! 479: #endif
! 480:
! 481: #ifdef ISC_PLATFORM_USETHREADS
! 482: /*
! 483: * There is no danger if isc_app_shutdown() is called before we wait
! 484: * for signals. Signals are blocked, so any such signal will simply
! 485: * be made pending and we will get it when we call sigwait().
! 486: */
! 487:
! 488: while (!want_shutdown) {
! 489: #ifdef HAVE_SIGWAIT
! 490: /*
! 491: * Wait for SIGHUP, SIGINT, or SIGTERM.
! 492: */
! 493: if (sigemptyset(&sset) != 0 ||
! 494: sigaddset(&sset, SIGHUP) != 0 ||
! 495: sigaddset(&sset, SIGINT) != 0 ||
! 496: sigaddset(&sset, SIGTERM) != 0) {
! 497: isc__strerror(errno, strbuf, sizeof(strbuf));
! 498: UNEXPECTED_ERROR(__FILE__, __LINE__,
! 499: "isc_app_run() sigsetops: %s", strbuf);
! 500: return (ISC_R_UNEXPECTED);
! 501: }
! 502:
! 503: #ifndef HAVE_UNIXWARE_SIGWAIT
! 504: result = sigwait(&sset, &sig);
! 505: if (result == 0) {
! 506: if (sig == SIGINT ||
! 507: sig == SIGTERM)
! 508: want_shutdown = ISC_TRUE;
! 509: else if (sig == SIGHUP)
! 510: want_reload = ISC_TRUE;
! 511: }
! 512:
! 513: #else /* Using UnixWare sigwait semantics. */
! 514: sig = sigwait(&sset);
! 515: if (sig >= 0) {
! 516: if (sig == SIGINT ||
! 517: sig == SIGTERM)
! 518: want_shutdown = ISC_TRUE;
! 519: else if (sig == SIGHUP)
! 520: want_reload = ISC_TRUE;
! 521: }
! 522:
! 523: #endif /* HAVE_UNIXWARE_SIGWAIT */
! 524: #else /* Don't have sigwait(). */
! 525: /*
! 526: * Listen for all signals.
! 527: */
! 528: if (sigemptyset(&sset) != 0) {
! 529: isc__strerror(errno, strbuf, sizeof(strbuf));
! 530: UNEXPECTED_ERROR(__FILE__, __LINE__,
! 531: "isc_app_run() sigsetops: %s", strbuf);
! 532: return (ISC_R_UNEXPECTED);
! 533: }
! 534: result = sigsuspend(&sset);
! 535: #endif /* HAVE_SIGWAIT */
! 536:
! 537: if (want_reload) {
! 538: want_reload = ISC_FALSE;
! 539: return (ISC_R_RELOAD);
! 540: }
! 541:
! 542: if (want_shutdown && blocked)
! 543: exit(1);
! 544: }
! 545:
! 546: #else /* ISC_PLATFORM_USETHREADS */
! 547:
! 548: (void)isc__taskmgr_dispatch();
! 549:
! 550: result = evloop();
! 551: if (result != ISC_R_SUCCESS)
! 552: return (result);
! 553:
! 554: #endif /* ISC_PLATFORM_USETHREADS */
! 555:
! 556: return (ISC_R_SUCCESS);
! 557: }
! 558:
! 559: isc_result_t
! 560: isc_app_shutdown(void) {
! 561: isc_boolean_t want_kill = ISC_TRUE;
! 562: char strbuf[ISC_STRERRORSIZE];
! 563:
! 564: LOCK(&lock);
! 565:
! 566: REQUIRE(running);
! 567:
! 568: if (shutdown_requested)
! 569: want_kill = ISC_FALSE;
! 570: else
! 571: shutdown_requested = ISC_TRUE;
! 572:
! 573: UNLOCK(&lock);
! 574:
! 575: if (want_kill) {
! 576: #ifdef HAVE_LINUXTHREADS
! 577: int result;
! 578:
! 579: result = pthread_kill(main_thread, SIGTERM);
! 580: if (result != 0) {
! 581: isc__strerror(result, strbuf, sizeof(strbuf));
! 582: UNEXPECTED_ERROR(__FILE__, __LINE__,
! 583: "isc_app_shutdown() pthread_kill: %s",
! 584: strbuf);
! 585: return (ISC_R_UNEXPECTED);
! 586: }
! 587: #else
! 588: if (kill(getpid(), SIGTERM) < 0) {
! 589: isc__strerror(errno, strbuf, sizeof(strbuf));
! 590: UNEXPECTED_ERROR(__FILE__, __LINE__,
! 591: "isc_app_shutdown() kill: %s", strbuf);
! 592: return (ISC_R_UNEXPECTED);
! 593: }
! 594: #endif
! 595: }
! 596:
! 597: return (ISC_R_SUCCESS);
! 598: }
! 599:
! 600: isc_result_t
! 601: isc_app_reload(void) {
! 602: isc_boolean_t want_kill = ISC_TRUE;
! 603: char strbuf[ISC_STRERRORSIZE];
! 604:
! 605: LOCK(&lock);
! 606:
! 607: REQUIRE(running);
! 608:
! 609: /*
! 610: * Don't send the reload signal if we're shutting down.
! 611: */
! 612: if (shutdown_requested)
! 613: want_kill = ISC_FALSE;
! 614:
! 615: UNLOCK(&lock);
! 616:
! 617: if (want_kill) {
! 618: #ifdef HAVE_LINUXTHREADS
! 619: int result;
! 620:
! 621: result = pthread_kill(main_thread, SIGHUP);
! 622: if (result != 0) {
! 623: isc__strerror(result, strbuf, sizeof(strbuf));
! 624: UNEXPECTED_ERROR(__FILE__, __LINE__,
! 625: "isc_app_reload() pthread_kill: %s",
! 626: strbuf);
! 627: return (ISC_R_UNEXPECTED);
! 628: }
! 629: #else
! 630: if (kill(getpid(), SIGHUP) < 0) {
! 631: isc__strerror(errno, strbuf, sizeof(strbuf));
! 632: UNEXPECTED_ERROR(__FILE__, __LINE__,
! 633: "isc_app_reload() kill: %s", strbuf);
! 634: return (ISC_R_UNEXPECTED);
! 635: }
! 636: #endif
! 637: }
! 638:
! 639: return (ISC_R_SUCCESS);
! 640: }
! 641:
! 642: void
! 643: isc_app_finish(void) {
! 644: DESTROYLOCK(&lock);
! 645: }
! 646:
! 647: void
! 648: isc_app_block(void) {
! 649: #ifdef ISC_PLATFORM_USETHREADS
! 650: sigset_t sset;
! 651: #endif /* ISC_PLATFORM_USETHREADS */
! 652: REQUIRE(running);
! 653: REQUIRE(!blocked);
! 654:
! 655: blocked = ISC_TRUE;
! 656: #ifdef ISC_PLATFORM_USETHREADS
! 657: blockedthread = pthread_self();
! 658: RUNTIME_CHECK(sigemptyset(&sset) == 0 &&
! 659: sigaddset(&sset, SIGINT) == 0 &&
! 660: sigaddset(&sset, SIGTERM) == 0);
! 661: RUNTIME_CHECK(pthread_sigmask(SIG_UNBLOCK, &sset, NULL) == 0);
! 662: #endif /* ISC_PLATFORM_USETHREADS */
! 663: }
! 664:
! 665: void
! 666: isc_app_unblock(void) {
! 667: #ifdef ISC_PLATFORM_USETHREADS
! 668: sigset_t sset;
! 669: #endif /* ISC_PLATFORM_USETHREADS */
! 670:
! 671: REQUIRE(running);
! 672: REQUIRE(blocked);
! 673:
! 674: blocked = ISC_FALSE;
! 675:
! 676: #ifdef ISC_PLATFORM_USETHREADS
! 677: REQUIRE(blockedthread == pthread_self());
! 678:
! 679: RUNTIME_CHECK(sigemptyset(&sset) == 0 &&
! 680: sigaddset(&sset, SIGINT) == 0 &&
! 681: sigaddset(&sset, SIGTERM) == 0);
! 682: RUNTIME_CHECK(pthread_sigmask(SIG_BLOCK, &sset, NULL) == 0);
! 683: #endif /* ISC_PLATFORM_USETHREADS */
! 684: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>