📄 app.c
字号:
* events. In the 'readytasks' case, there may be no * timeout event actually, but there is no other way * to reduce the overhead. * Note that we do not have to worry about the case * where a new timer is inserted during the select() * call, since this loop only runs in the non-thread * mode. */ isc__timermgr_dispatch(); } if (n > 0) (void)isc__socketmgr_dispatch(&readfds, &writefds, maxfd); (void)isc__taskmgr_dispatch(); if (want_reload) { want_reload = ISC_FALSE; return (ISC_R_RELOAD); } } return (ISC_R_SUCCESS);}/* * This is a gross hack to support waiting for condition * variables in nonthreaded programs in a limited way; * see lib/isc/nothreads/include/isc/condition.h. * We implement isc_condition_wait() by entering the * event loop recursively until the want_shutdown flag * is set by isc_condition_signal(). *//* * True iff we are currently executing in the recursive * event loop. */static isc_boolean_t in_recursive_evloop = ISC_FALSE;/* * True iff we are exiting the event loop as the result of * a call to isc_condition_signal() rather than a shutdown * or reload. */static isc_boolean_t signalled = ISC_FALSE;isc_result_tisc__nothread_wait_hack(isc_condition_t *cp, isc_mutex_t *mp) { isc_result_t result; UNUSED(cp); UNUSED(mp); INSIST(!in_recursive_evloop); in_recursive_evloop = ISC_TRUE; INSIST(*mp == 1); /* Mutex must be locked on entry. */ --*mp; result = evloop(); if (result == ISC_R_RELOAD) want_reload = ISC_TRUE; if (signalled) { want_shutdown = ISC_FALSE; signalled = ISC_FALSE; } ++*mp; in_recursive_evloop = ISC_FALSE; return (ISC_R_SUCCESS);}isc_result_tisc__nothread_signal_hack(isc_condition_t *cp) { UNUSED(cp); INSIST(in_recursive_evloop); want_shutdown = ISC_TRUE; signalled = ISC_TRUE; return (ISC_R_SUCCESS);} #endif /* ISC_PLATFORM_USETHREADS */isc_result_tisc_app_run(void) { int result; isc_event_t *event, *next_event; isc_task_t *task;#ifdef ISC_PLATFORM_USETHREADS sigset_t sset; char strbuf[ISC_STRERRORSIZE];#endif /* ISC_PLATFORM_USETHREADS */#ifdef HAVE_SIGWAIT int sig;#endif#ifdef HAVE_LINUXTHREADS REQUIRE(main_thread == pthread_self());#endif LOCK(&lock); if (!running) { running = ISC_TRUE; /* * Post any on-run events (in FIFO order). */ for (event = ISC_LIST_HEAD(on_run); event != NULL; event = next_event) { next_event = ISC_LIST_NEXT(event, ev_link); ISC_LIST_UNLINK(on_run, event, ev_link); task = event->ev_sender; event->ev_sender = NULL; isc_task_sendanddetach(&task, &event); } } UNLOCK(&lock);#ifndef HAVE_SIGWAIT /* * Catch SIGHUP. * * We do this here to ensure that the signal handler is installed * (i.e. that it wasn't a "one-shot" handler). */ result = handle_signal(SIGHUP, reload_action); if (result != ISC_R_SUCCESS) return (ISC_R_SUCCESS);#endif#ifdef ISC_PLATFORM_USETHREADS /* * There is no danger if isc_app_shutdown() is called before we wait * for signals. Signals are blocked, so any such signal will simply * be made pending and we will get it when we call sigwait(). */ while (!want_shutdown) {#ifdef HAVE_SIGWAIT /* * Wait for SIGHUP, SIGINT, or SIGTERM. */ if (sigemptyset(&sset) != 0 || sigaddset(&sset, SIGHUP) != 0 || sigaddset(&sset, SIGINT) != 0 || sigaddset(&sset, SIGTERM) != 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_run() sigsetops: %s", strbuf); return (ISC_R_UNEXPECTED); }#ifndef HAVE_UNIXWARE_SIGWAIT result = sigwait(&sset, &sig); if (result == 0) { if (sig == SIGINT || sig == SIGTERM) want_shutdown = ISC_TRUE; else if (sig == SIGHUP) want_reload = ISC_TRUE; }#else /* Using UnixWare sigwait semantics. */ sig = sigwait(&sset); if (sig >= 0) { if (sig == SIGINT || sig == SIGTERM) want_shutdown = ISC_TRUE; else if (sig == SIGHUP) want_reload = ISC_TRUE; }#endif /* HAVE_UNIXWARE_SIGWAIT */#else /* Don't have sigwait(). */ /* * Listen for all signals. */ if (sigemptyset(&sset) != 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_run() sigsetops: %s", strbuf); return (ISC_R_UNEXPECTED); } result = sigsuspend(&sset);#endif /* HAVE_SIGWAIT */ if (want_reload) { want_reload = ISC_FALSE; return (ISC_R_RELOAD); } if (want_shutdown && blocked) exit(1); }#else /* ISC_PLATFORM_USETHREADS */ (void)isc__taskmgr_dispatch(); result = evloop(); if (result != ISC_R_SUCCESS) return (result);#endif /* ISC_PLATFORM_USETHREADS */ return (ISC_R_SUCCESS);}isc_result_tisc_app_shutdown(void) { isc_boolean_t want_kill = ISC_TRUE; char strbuf[ISC_STRERRORSIZE]; LOCK(&lock); REQUIRE(running); if (shutdown_requested) want_kill = ISC_FALSE; else shutdown_requested = ISC_TRUE; UNLOCK(&lock); if (want_kill) {#ifdef HAVE_LINUXTHREADS int result; result = pthread_kill(main_thread, SIGTERM); if (result != 0) { isc__strerror(result, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_shutdown() pthread_kill: %s", strbuf); return (ISC_R_UNEXPECTED); }#else if (kill(getpid(), SIGTERM) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_shutdown() kill: %s", strbuf); return (ISC_R_UNEXPECTED); }#endif } return (ISC_R_SUCCESS);}isc_result_tisc_app_reload(void) { isc_boolean_t want_kill = ISC_TRUE; char strbuf[ISC_STRERRORSIZE]; LOCK(&lock); REQUIRE(running); /* * Don't send the reload signal if we're shutting down. */ if (shutdown_requested) want_kill = ISC_FALSE; UNLOCK(&lock); if (want_kill) {#ifdef HAVE_LINUXTHREADS int result; result = pthread_kill(main_thread, SIGHUP); if (result != 0) { isc__strerror(result, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_reload() pthread_kill: %s", strbuf); return (ISC_R_UNEXPECTED); }#else if (kill(getpid(), SIGHUP) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_reload() kill: %s", strbuf); return (ISC_R_UNEXPECTED); }#endif } return (ISC_R_SUCCESS);}voidisc_app_finish(void) { DESTROYLOCK(&lock);}voidisc_app_block(void) {#ifdef ISC_PLATFORM_USETHREADS sigset_t sset;#endif /* ISC_PLATFORM_USETHREADS */ REQUIRE(running); REQUIRE(!blocked); blocked = ISC_TRUE;#ifdef ISC_PLATFORM_USETHREADS blockedthread = pthread_self(); RUNTIME_CHECK(sigemptyset(&sset) == 0 && sigaddset(&sset, SIGINT) == 0 && sigaddset(&sset, SIGTERM) == 0); RUNTIME_CHECK(pthread_sigmask(SIG_UNBLOCK, &sset, NULL) == 0);#endif /* ISC_PLATFORM_USETHREADS */}voidisc_app_unblock(void) {#ifdef ISC_PLATFORM_USETHREADS sigset_t sset;#endif /* ISC_PLATFORM_USETHREADS */ REQUIRE(running); REQUIRE(blocked); blocked = ISC_FALSE;#ifdef ISC_PLATFORM_USETHREADS REQUIRE(blockedthread == pthread_self()); RUNTIME_CHECK(sigemptyset(&sset) == 0 && sigaddset(&sset, SIGINT) == 0 && sigaddset(&sset, SIGTERM) == 0); RUNTIME_CHECK(pthread_sigmask(SIG_BLOCK, &sset, NULL) == 0);#endif /* ISC_PLATFORM_USETHREADS */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -