Improve main thread detection

Now properly checks if configuration and diagnostics functions are ran in either
main() or in the admin worker. This is useful for debugging and enforcing
thread safety.

Also, monitors are now started and stopped in the admin worker.
This commit is contained in:
Esa Korhonen 2019-06-06 10:17:17 +03:00
parent 9d0c6b908a
commit 1514a77345
4 changed files with 46 additions and 18 deletions

View File

@ -1442,10 +1442,15 @@ int main(int argc, char** argv)
rc = MAXSCALE_NOSERVICES;
maxscale_shutdown();
}
else if (daemon_mode)
else
{
// Successful start, notify the parent process that it can exit.
write_child_exit_code(daemon_pipe[1], rc);
if (daemon_mode)
{
// Successful start, notify the parent process that it can exit.
write_child_exit_code(daemon_pipe[1], rc);
}
/** Start all monitors */
MonitorManager::start_all_monitors();
}
};
@ -2188,9 +2193,6 @@ int main(int argc, char** argv)
goto return_main;
}
/** Start all monitors */
MonitorManager::start_all_monitors();
if (cnf->config_check)
{
MXS_NOTICE("Configuration was successfully verified.");
@ -2247,6 +2249,8 @@ int main(int argc, char** argv)
worker = RoutingWorker::get(RoutingWorker::MAIN);
mxb_assert(worker);
// Configuration read and items created. Changes should now come through the main routing worker.
set_admin_worker(worker);
if (!worker->execute(do_startup, RoutingWorker::EXECUTE_QUEUED))
{
const char* logerr = "Failed to queue startup task.";
@ -2257,19 +2261,17 @@ int main(int argc, char** argv)
main_worker->run();
/*< Stop all monitors */
MonitorManager::stop_all_monitors();
/*< Destroy all monitors */
MonitorManager::destroy_all_monitors();
/*<
* Wait for worker threads to exit.
*/
RoutingWorker::join_workers();
MXS_NOTICE("All workers have shut down.");
set_admin_worker(nullptr); // Main worker has quit, re-assign to non-worker.
/*< Destroy all monitors */
MonitorManager::destroy_all_monitors();
maxscale_start_teardown();
/*<

View File

@ -18,8 +18,6 @@
#include <maxscale/maxscale.h>
MXS_BEGIN_DECLS
/**
* Initiate shutdown of MaxScale.
*
@ -39,4 +37,6 @@ void maxscale_reset_starttime(void);
bool maxscale_teardown_in_progress();
void maxscale_start_teardown();
MXS_END_DECLS
bool running_in_admin_thread();
void set_admin_worker(const mxb::Worker* admin_worker);

View File

@ -11,6 +11,7 @@
* Public License.
*/
#include <maxscale/ccdefs.hh>
#include <maxscale/maxscale.h>
#include <time.h>
@ -21,9 +22,19 @@
#include "internal/maxscale.hh"
#include "internal/service.hh"
#include "internal/admin.hh"
#include "internal/monitormanager.hh"
static time_t started;
namespace
{
struct ThisUnit
{
std::atomic<const mxb::Worker*> admin_worker {nullptr};
};
ThisUnit this_unit;
}
void maxscale_reset_starttime(void)
{
started = time(0);
@ -58,6 +69,9 @@ int maxscale_shutdown()
mxs::MainWorker::get().shutdown();
}
/*< Stop all monitors */
MonitorManager::stop_all_monitors();
mxs_admin_shutdown();
mxs::RoutingWorker::shutdown_all();
};
@ -80,3 +94,15 @@ void maxscale_start_teardown()
{
teardown_in_progress = true;
}
bool running_in_admin_thread()
{
auto current_worker = mxb::Worker::get_current();
return current_worker == this_unit.admin_worker.load(std::memory_order_acquire);
}
void set_admin_worker(const mxb::Worker* admin_worker)
{
this_unit.admin_worker.store(admin_worker, std::memory_order_release);
}

View File

@ -46,6 +46,7 @@
#include "internal/config.hh"
#include "internal/externcmd.hh"
#include "internal/maxscale.hh"
#include "internal/monitor.hh"
#include "internal/modules.hh"
#include "internal/server.hh"
@ -1212,8 +1213,7 @@ string Monitor::get_server_monitor(const SERVER* server)
bool Monitor::is_admin_thread()
{
mxb::Worker* current = mxb::Worker::get_current();
return current == nullptr || current == mxs_rworker_get(MXS_RWORKER_MAIN);
return running_in_admin_thread();
}
/**