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; }
lagopus_result_t global_state_wait_for(global_state_t s_wait_for, global_state_t *cur_sptr, shutdown_grace_level_t *cur_gptr, lagopus_chrono_t nsec) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; if (IS_VALID_GLOBAL_STATE(s_wait_for) == true) { s_lock(); { recheck: if ((int)s_gs < (int)s_wait_for && IS_GLOBAL_STATE_SHUTDOWN(s_gs) == false) { ret = lagopus_cond_wait(&s_cond, &s_lck, nsec); if (ret == LAGOPUS_RESULT_OK) { goto recheck; } } else { if (cur_sptr != NULL) { *cur_sptr = s_gs; } if (cur_gptr != NULL) { *cur_gptr = s_gl; } if ((int)s_gs >= (int)s_wait_for) { ret = LAGOPUS_RESULT_OK; } else if (IS_GLOBAL_STATE_SHUTDOWN(s_gs) == true && IS_GLOBAL_STATE_SHUTDOWN(s_wait_for) == false) { ret = LAGOPUS_RESULT_NOT_OPERATIONAL; } else { ret = LAGOPUS_RESULT_OK; } } } s_unlock(); } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
lagopus_result_t global_state_request_shutdown(shutdown_grace_level_t l) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; if (IS_VALID_SHUTDOWN(l) == true) { s_lock(); { if (IS_GLOBAL_STATE_SHUTDOWN(s_gs) == false && s_gs != GLOBAL_STATE_REQUEST_SHUTDOWN) { if (s_is_valid_state(GLOBAL_STATE_REQUEST_SHUTDOWN) == true) { s_gs = GLOBAL_STATE_REQUEST_SHUTDOWN; s_gl = l; (void)lagopus_cond_notify(&s_cond, true); /* * Wait until someone changes the state to * GLOBAL_STATE_ACCEPT_SHUTDOWN */ recheck: if (IS_GLOBAL_STATE_SHUTDOWN(s_gs) == false) { if ((ret = lagopus_cond_wait(&s_cond, &s_lck, -1LL)) == LAGOPUS_RESULT_OK) { goto recheck; } } } else { ret = LAGOPUS_RESULT_INVALID_STATE_TRANSITION; } } } s_unlock(); } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }