int main(int argc, char *argv[]) { struct thread_state state[1]; struct exception_context *the_exception_context = state->ec; struct exception e; init_exception_context(the_exception_context); try { bar(state); /* no exceptions */ bar(state); /* exception will be caught by bar(), looks okay to us */ bar(state); /* bar() will rethrow the exception */ fprintf(stderr, "we won't get here\n"); } catch(e) { switch (e.flavor) { case okay: break; case barf: fprintf(stderr, "main caught barf (info == %s): %s\n", e.info.barf, e.msg); break; case screwup: fprintf(stderr, "main caught screwup (info == %ld): %s\n", e.info.screwup, e.msg); break; default: fprintf(stderr, "main caught unknown exception\n"); } } return EXIT_SUCCESS; }
static void WINAPI nx_win32_svc_main(DWORD argc, LPTSTR *argv) { nx_context_t thread_context; nx_exception_t e; if ( _nxlog_initializer == 0 ) { // running from service manager ASSERT(nx_init(&argc, &argv, NULL) == TRUE); nxlog_init(&nxlog); nx_logger_disable_foreground(); } else if ( _nxlog_initializer != apr_os_thread_current() ) { // service dispatcher runs in a new thread, we need // to initialize the exception context. _nxlog_initializer = apr_os_thread_current(); memset(&thread_context, 0, sizeof(nx_context_t)); init_exception_context(&thread_context.exception_context); apr_threadkey_private_set(&thread_context, nx_get_context_key()); } log_debug("nx_win32_svc_main"); try { // read config cache nx_config_cache_read(); log_debug("nxlog cache read"); // load DSO and read and verify module config nx_ctx_config_modules(nxlog.ctx); log_debug("nxlog config OK"); // initialize modules nx_ctx_init_modules(nxlog.ctx); // initialize log routes nx_ctx_init_routes(nxlog.ctx); nx_ctx_init_jobs(nxlog.ctx); nx_ctx_restore_queues(nxlog.ctx); // setup threadpool nxlog_create_threads(&nxlog); // start modules nx_ctx_start_modules(nxlog.ctx); if ( nxlog.foreground != TRUE ) { // register to service manager svc_status_handle = RegisterServiceCtrlHandler("nxlog", nx_win32_svc_change); if ( svc_status_handle == 0 ) { nx_win32_error("RegisterServiceCtrlHandler() failed, couldn't register the service control handler"); } // Signal to svc manager that we are running svc_status.dwWin32ExitCode = 0; svc_status.dwServiceSpecificExitCode = 0; svc_status.dwCheckPoint = 0; svc_status.dwWaitHint = 0; svc_status.dwServiceType = SERVICE_WIN32; svc_status.dwCurrentState = SERVICE_RUNNING; svc_status.dwControlsAccepted = SERVICE_ACCEPT_STOP; if ( SetServiceStatus(svc_status_handle, &svc_status) == FALSE ) { nx_win32_error("Cannot send start service status update"); } } log_info(PACKAGE"-"VERSION_STRING" started"); } catch(e) { log_exception(e); log_error("exiting..."); svc_status.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(svc_status_handle, &svc_status); exit(e.code); } // mainloop nxlog_mainloop(&nxlog, FALSE); nxlog_shutdown(&nxlog); if ( nxlog.foreground != TRUE ) { // Signal back that we are stopped svc_status.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(svc_status_handle, &svc_status); log_debug("service stopped"); } nxlog_exit_function(); }