diff --git a/maxutils/maxbase/include/maxbase/worker.hh b/maxutils/maxbase/include/maxbase/worker.hh index 7ad49a5bb..5412bf4f8 100644 --- a/maxutils/maxbase/include/maxbase/worker.hh +++ b/maxutils/maxbase/include/maxbase/worker.hh @@ -41,17 +41,18 @@ struct WORKER_STATISTICS N_QUEUE_TIMES = 30 }; - int64_t n_read = 0; /*< Number of read events */ - int64_t n_write = 0; /*< Number of write events */ - int64_t n_error = 0; /*< Number of error events */ - int64_t n_hup = 0; /*< Number of hangup events */ - int64_t n_accept = 0; /*< Number of accept events */ - int64_t n_polls = 0; /*< Number of poll cycles */ - int64_t n_pollev = 0; /*< Number of polls returning events */ - int64_t evq_avg = 0; /*< Average event queue length */ - int64_t evq_max = 0; /*< Maximum event queue length */ - int64_t maxqtime = 0; - int64_t maxexectime = 0; + int64_t n_read = 0; /*< Number of read events */ + int64_t n_write = 0; /*< Number of write events */ + int64_t n_error = 0; /*< Number of error events */ + int64_t n_hup = 0; /*< Number of hangup events */ + int64_t n_accept = 0; /*< Number of accept events */ + int64_t n_polls = 0; /*< Number of poll cycles */ + int64_t n_pollev = 0; /*< Number of polls returning events */ + int64_t evq_avg = 0; /*< Average event queue length */ + int64_t evq_max = 0; /*< Maximum event queue length */ + int64_t maxqtime = 0; + int64_t maxexectime = 0; + std::array n_fds {}; /*< Number of wakeups with particular n_fds value */ std::array qtimes {}; std::array exectimes {}; diff --git a/maxutils/maxbase/src/worker.cc b/maxutils/maxbase/src/worker.cc index 64922e427..5c6cb2172 100644 --- a/maxutils/maxbase/src/worker.cc +++ b/maxutils/maxbase/src/worker.cc @@ -111,7 +111,7 @@ uint64_t WorkerLoad::get_time_ms() int rv = clock_gettime(CLOCK_MONOTONIC_COARSE, &t); if (rv != 0) { - mxb_assert(errno == EINVAL); // CLOCK_MONOTONIC_COARSE not supported. + mxb_assert(errno == EINVAL); // CLOCK_MONOTONIC_COARSE not supported. rv = clock_gettime(CLOCK_MONOTONIC, &t); mxb_assert(rv == 0); } @@ -519,9 +519,19 @@ bool Worker::call(function func, execute_mode_t mode) bool Worker::post_message(uint32_t msg_id, intptr_t arg1, intptr_t arg2) { // NOTE: No logging here, this function must be signal safe. - MessageQueue::Message message(msg_id, arg1, arg2); + bool rval = false; - return m_pQueue->post(message); + // TODO: Enable and fix this in develop and/or 2.4: The deletion of rworker_local is done after the + // workers have stopped and it triggers this assertion. + // mxb_assert(state() != Worker::STOPPED); + + if (state() != Worker::STOPPED) + { + MessageQueue::Message message(msg_id, arg1, arg2); + rval = m_pQueue->post(message); + } + + return rval; } void Worker::run(mxb::Semaphore* pSem) diff --git a/server/core/admin.cc b/server/core/admin.cc index 16431f249..a00d97fd9 100644 --- a/server/core/admin.cc +++ b/server/core/admin.cc @@ -424,6 +424,7 @@ bool mxs_admin_init() void mxs_admin_shutdown() { MHD_stop_daemon(http_daemon); + MXS_NOTICE("Stopped MaxScale REST API"); } bool mxs_admin_https_enabled() diff --git a/server/core/gateway.cc b/server/core/gateway.cc index 07bd72ed4..7700b7a85 100644 --- a/server/core/gateway.cc +++ b/server/core/gateway.cc @@ -2255,9 +2255,6 @@ int main(int argc, char** argv) mxb_assert(worker); worker->run(); - /** Stop administrative interface */ - mxs_admin_shutdown(); - /*< Stop all monitors */ monitor_stop_all(); diff --git a/server/core/misc.cc b/server/core/misc.cc index 2098ad95c..a1476e389 100644 --- a/server/core/misc.cc +++ b/server/core/misc.cc @@ -19,6 +19,7 @@ #include "internal/maxscale.h" #include "internal/service.hh" +#include "internal/admin.hh" static time_t started; @@ -50,7 +51,12 @@ int maxscale_shutdown() if (n == 0) { - mxs::RoutingWorker::shutdown_all(); + auto w = mxs::RoutingWorker::get(mxs::RoutingWorker::MAIN); + w->execute( + []() { + mxs_admin_shutdown(); + mxs::RoutingWorker::shutdown_all(); + }, nullptr, mxs::RoutingWorker::EXECUTE_QUEUED); } return n + 1;