isc_result_t isc__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(&isc_g_appctx); if (result == ISC_R_RELOAD) isc_g_appctx.want_reload = ISC_TRUE; if (signalled) { isc_g_appctx.want_shutdown = ISC_FALSE; signalled = ISC_FALSE; } ++*mp; in_recursive_evloop = ISC_FALSE; return (ISC_R_SUCCESS); }
static void *event_loop(void *arg) { net_client_t *nc = (net_client_t *)arg; evloop(nc->epfd,&nc->endgame); return NULL; }
static void *event_loop(void *arg) { net_client_t *nc = (net_client_t *)arg; log_error(nc->log,"nc evloop thread id:%ld!",syscall(SYS_gettid)); evloop(NULL,nc->epfd,&nc->endgame); return NULL; }
int main(int argc,char *argv[]) { assert(argc >=3); rain_loger_init(); rain_ctx_init(154); char *dir = malloc(1024); getcwd(dir,1024); strcat(dir,"/routine/"); //printf("dir:%s %s %s %s\n",dir,argv[0],argv[1],argv[2]); rain_module_init(dir); free(dir); rain_timer_init(); rain_rpc_init(); rain_lifequeue_int(); sig_init(); rain_ctx_t * ctx = rain_ctx_new(0,argv[1],argv[2]); if(ctx == NULL){ exit(-1); } //routine_t rid = rain_ctx_getid(ctx); int len = 4; pthread_t threads[len]; int i; for(i=0; i<len; i++){ pthread_create(&threads[i],NULL,worker,NULL); } evloop(NULL); /* pthread_t thread_ev; pthread_create(&thread_ev,NULL,evloop,NULL); for(i=0; i<len; i++){ pthread_join(threads[i],NULL); } pthread_join(thread_ev,NULL);*/ exit(0); }
ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxrun(isc_appctx_t *ctx0) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; int result; isc_event_t *event, *next_event; isc_task_t *task; #ifdef USE_THREADS_SINGLECTX sigset_t sset; char strbuf[ISC_STRERRORSIZE]; #ifdef HAVE_SIGWAIT int sig; #endif #endif /* USE_THREADS_SINGLECTX */ REQUIRE(VALID_APPCTX(ctx)); #ifdef HAVE_LINUXTHREADS REQUIRE(main_thread == pthread_self()); #endif LOCK(&ctx->lock); if (!ctx->running) { ctx->running = ISC_TRUE; /* * Post any on-run events (in FIFO order). */ for (event = ISC_LIST_HEAD(ctx->on_run); event != NULL; event = next_event) { next_event = ISC_LIST_NEXT(event, ev_link); ISC_LIST_UNLINK(ctx->on_run, event, ev_link); task = event->ev_sender; event->ev_sender = NULL; isc_task_sendanddetach(&task, &event); } } UNLOCK(&ctx->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). */ if (ctx == &isc_g_appctx) { result = handle_signal(SIGHUP, reload_action); if (result != ISC_R_SUCCESS) return (ISC_R_SUCCESS); } #endif #ifdef USE_THREADS_SINGLECTX /* * When we are using multiple contexts, we don't rely on signals. */ if (ctx != &isc_g_appctx) return (ISC_R_SUCCESS); /* * 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 (!ctx->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) ctx->want_shutdown = ISC_TRUE; else if (sig == SIGHUP) ctx->want_reload = ISC_TRUE; } #else /* Using UnixWare sigwait semantics. */ sig = sigwait(&sset); if (sig >= 0) { if (sig == SIGINT || sig == SIGTERM) ctx->want_shutdown = ISC_TRUE; else if (sig == SIGHUP) ctx->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 (ctx->want_reload) { ctx->want_reload = ISC_FALSE; return (ISC_R_RELOAD); } if (ctx->want_shutdown && ctx->blocked) exit(1); } #else /* USE_THREADS_SINGLECTX */ (void)isc__taskmgr_dispatch(ctx->taskmgr); result = evloop(ctx); if (result != ISC_R_SUCCESS) return (result); #endif /* USE_THREADS_SINGLECTX */ return (ISC_R_SUCCESS); }
isc_result_t isc__app_ctxrun(isc_appctx_t *ctx0) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; int result; isc_event_t *event, *next_event; isc_task_t *task; #ifdef ISC_PLATFORM_USETHREADS sigset_t sset; char strbuf[ISC_STRERRORSIZE]; #ifdef HAVE_SIGWAIT int sig; #endif /* HAVE_SIGWAIT */ #endif /* ISC_PLATFORM_USETHREADS */ REQUIRE(VALID_APPCTX(ctx)); #ifdef HAVE_LINUXTHREADS REQUIRE(main_thread == pthread_self()); #endif LOCK(&ctx->lock); if (!ctx->running) { ctx->running = ISC_TRUE; /* * Post any on-run events (in FIFO order). */ for (event = ISC_LIST_HEAD(ctx->on_run); event != NULL; event = next_event) { next_event = ISC_LIST_NEXT(event, ev_link); ISC_LIST_UNLINK(ctx->on_run, event, ev_link); task = event->ev_sender; event->ev_sender = NULL; isc_task_sendanddetach(&task, &event); } } UNLOCK(&ctx->lock); #ifndef ISC_PLATFORM_USETHREADS if (isc_bind9 && ctx == &isc_g_appctx) { result = handle_signal(SIGHUP, reload_action); if (result != ISC_R_SUCCESS) return (ISC_R_SUCCESS); } (void) isc__taskmgr_dispatch(ctx->taskmgr); result = evloop(ctx); return (result); #else /* ISC_PLATFORM_USETHREADS */ /* * BIND9 internal tools using multiple contexts do not * rely on signal. */ if (isc_bind9 && ctx != &isc_g_appctx) return (ISC_R_SUCCESS); /* * 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 (!ctx->want_shutdown) { #ifdef HAVE_SIGWAIT if (isc_bind9) { /* * BIND9 internal; single context: * 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) ctx->want_shutdown = ISC_TRUE; else if (sig == SIGHUP) ctx->want_reload = ISC_TRUE; } #else /* Using UnixWare sigwait semantics. */ sig = sigwait(&sset); if (sig >= 0) { if (sig == SIGINT || sig == SIGTERM) ctx->want_shutdown = ISC_TRUE; else if (sig == SIGHUP) ctx->want_reload = ISC_TRUE; } #endif /* HAVE_UNIXWARE_SIGWAIT */ } else { /* * External, or BIND9 using multiple contexts: * wait until woken up. */ LOCK(&ctx->readylock); if (ctx->want_shutdown) { /* shutdown() won the race. */ UNLOCK(&ctx->readylock); break; } if (!ctx->want_reload) WAIT(&ctx->ready, &ctx->readylock); UNLOCK(&ctx->readylock); } #else /* Don't have sigwait(). */ if (isc_bind9) { /* * BIND9 internal; single context: * Install a signal handler for SIGHUP, then wait for * all signals. */ result = handle_signal(SIGHUP, reload_action); if (result != ISC_R_SUCCESS) return (ISC_R_SUCCESS); if (sigemptyset(&sset) != 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_run() sigsetops: %s", strbuf); return (ISC_R_UNEXPECTED); } #ifdef HAVE_GPERFTOOLS_PROFILER if (sigaddset(&sset, SIGALRM) != 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_run() sigsetops: %s", strbuf); return (ISC_R_UNEXPECTED); } #endif result = sigsuspend(&sset); } else { /* * External, or BIND9 using multiple contexts: * wait until woken up. */ LOCK(&ctx->readylock); if (ctx->want_shutdown) { /* shutdown() won the race. */ UNLOCK(&ctx->readylock); break; } if (!ctx->want_reload) WAIT(&ctx->ready, &ctx->readylock); UNLOCK(&ctx->readylock); } #endif /* HAVE_SIGWAIT */ if (ctx->want_reload) { ctx->want_reload = ISC_FALSE; return (ISC_R_RELOAD); } if (ctx->want_shutdown && ctx->blocked) exit(1); } return (ISC_R_SUCCESS); #endif /* ISC_PLATFORM_USETHREADS */ }