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;
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}