static gallus_result_t s_main(const gallus_thread_t *tptr, void *arg) { gallus_result_t ret = GALLUS_RESULT_ANY_FAILURES; (void)arg; if (tptr != NULL) { null_thread_t nptr = (null_thread_t)*tptr; if (nptr != NULL) { global_state_t s; shutdown_grace_level_t l; gallus_msg_debug(1, "waiting for the world changes to " "GLOBAL_STATE_STARTED ...\n"); while ((ret = global_state_wait_for(GLOBAL_STATE_STARTED, &s, &l, 1000LL * 1000LL * 100LL)) == GALLUS_RESULT_TIMEDOUT) { gallus_msg_debug(1, "still waiting for the world changes to " "GLOBAL_STATE_STARTED ...\n"); } if (ret != GALLUS_RESULT_OK) { gallus_perror(ret); if (ret == GALLUS_RESULT_NOT_OPERATIONAL) { /* * Whole the system is about to be shutdown. Just exit. */ if (IS_GLOBAL_STATE_SHUTDOWN(s) == true) { goto done; } else { gallus_exit_fatal("must not happen.\n"); } } } else { if (s != GLOBAL_STATE_STARTED) { gallus_exit_fatal("must not happen, too.\n"); } } gallus_msg_debug(1, "wait done.\n"); sleep(1); if ((ret = global_state_request_shutdown(nptr->m_gl)) != GALLUS_RESULT_OK) { gallus_perror(ret); goto done; } gallus_msg_debug(1, "request shutdown.\n"); ret = GALLUS_RESULT_OK; } } done: return ret; }
void test_epilogue(void) { lagopus_result_t r; channel_mgr_finalize(); r = global_state_request_shutdown(SHUTDOWN_GRACEFULLY); TEST_ASSERT_EQUAL(r, LAGOPUS_RESULT_OK); lagopus_mainloop_wait_thread(); }
static inline void s_shutdown(shutdown_grace_level_t level) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; if ((ret = global_state_request_shutdown(level)) == LAGOPUS_RESULT_OK) { lagopus_msg_info("The shutdown request accepted.\n"); } else { lagopus_perror(ret); lagopus_msg_error("Can't request shutdown.\n"); } }
void test_epilogue(void) { lagopus_result_t r; run = false; channel_mgr_finalize(); r = global_state_request_shutdown(SHUTDOWN_GRACEFULLY); TEST_ASSERT_EQUAL(r, LAGOPUS_RESULT_OK); lagopus_mainloop_wait_thread(); close(s4); close(s6); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, dp_bridge_destroy(bridge_name)); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, dp_port_destroy(port_name)); TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, dp_interface_destroy(interface_name)); dp_api_fini(); }
static void s_term_handler(int sig) { lagopus_result_t r = LAGOPUS_RESULT_ANY_FAILURES; global_state_t gs = GLOBAL_STATE_UNKNOWN; if ((r = global_state_get(&gs)) == LAGOPUS_RESULT_OK) { if ((int)gs == (int)GLOBAL_STATE_STARTED) { shutdown_grace_level_t l = SHUTDOWN_UNKNOWN; if (sig == SIGTERM || sig == SIGINT) { l = SHUTDOWN_GRACEFULLY; } else if (sig == SIGQUIT) { l = SHUTDOWN_RIGHT_NOW; } if (IS_VALID_SHUTDOWN(l) == true) { lagopus_msg_info("About to request shutdown(%s)...\n", (l == SHUTDOWN_RIGHT_NOW) ? "RIGHT_NOW" : "GRACEFULLY"); if ((r = global_state_request_shutdown(l)) == LAGOPUS_RESULT_OK) { lagopus_msg_info("The shutdown request accepted.\n"); } else { lagopus_perror(r); lagopus_msg_error("can't request shutdown.\n"); } } } else if ((int)gs < (int)GLOBAL_STATE_STARTED) { if (sig == SIGTERM || sig == SIGINT || sig == SIGQUIT) { s_got_term_sig = true; } } else { lagopus_msg_debug(5, "The system is already shutting down.\n"); } } }
static void s_atexit_handler(void) { if (likely(__sync_fetch_and_add(&s_is_exit_handler_called, 1) == 0)) { gallus_result_t r; r = s_trylock(); if (likely(r == GALLUS_RESULT_OK)) { bool is_finished_cleanly = false; if (s_n_modules > 0) { recheck: mbar(); if (s_gstate == MODULE_GLOBAL_STATE_UNKNOWN) { is_finished_cleanly = true; } else if (s_gstate == MODULE_GLOBAL_STATE_STARTED) { (void)global_state_request_shutdown(SHUTDOWN_RIGHT_NOW); } else if (s_gstate != MODULE_GLOBAL_STATE_FINALIZED) { r = s_wait(100LL * 1000LL * 1000LL); if (r == GALLUS_RESULT_OK) { goto recheck; } else if (r == GALLUS_RESULT_TIMEDOUT) { gallus_msg_warning("Module finalization seems not completed.\n"); } else { gallus_perror(r); gallus_msg_error("module finalization wait failed.\n"); } } else { is_finished_cleanly = true; } } if (is_finished_cleanly == true) { s_is_unloading = true; mbar(); } s_unlock(); } else if (r == GALLUS_RESULT_BUSY) { /* * The lock failure. Snoop s_gstate anyway. Note that it's safe * since the modules are always accessesed only by a single * thread and the thread is calling exit(3) at this moment. */ if (s_gstate == MODULE_GLOBAL_STATE_UNKNOWN) { /* * No modules are initialized. Just exit cleanly and let all * the static destructors run. */ s_is_unloading = true; mbar(); } else { if (pthread_self() == s_initializer_tid) { /* * Made sure that this very thread is the module * initializer. So we can safely unlock the lock. */ switch (s_gstate) { case MODULE_GLOBAL_STATE_FINALIZING: case MODULE_GLOBAL_STATE_FINALIZED: case MODULE_GLOBAL_STATE_UNKNOWN: { s_unlock(); /* * Nothing is needed to do. */ break; } case MODULE_GLOBAL_STATE_INITIALIZING: case MODULE_GLOBAL_STATE_INITIALIZED: case MODULE_GLOBAL_STATE_STARTING: { s_unlock(); /* * With this only modules safely finalizable so far are * finalized. */ gallus_module_finalize_all(); break; } case MODULE_GLOBAL_STATE_STARTED: { s_unlock(); (void)global_state_request_shutdown(SHUTDOWN_RIGHT_NOW); break; } case MODULE_GLOBAL_STATE_SHUTTINGDOWN: case MODULE_GLOBAL_STATE_STOPPING: case MODULE_GLOBAL_STATE_WAITING: case MODULE_GLOBAL_STATE_SHUTDOWN: { s_unlock(); /* * There's nothing we can do at this moment. */ break; } default: { s_unlock(); break; } } } else { /* (pthread_self() == s_initializer_tid) */ /* * This menas that a thread other than module initialized is * locking the lock. There's nothing we can do at this moment. */ return; } } /* (s_gstate == MODULE_GLOBAL_STATE_UNKNOWN) */ } } }