Example #1
0
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;
}
Example #2
0
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();
}
Example #3
0
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");
  }
}
Example #4
0
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();
}
Example #5
0
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");
    }
  }

}
Example #6
0
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) */
    }
  }
}