diff --git a/server/core/gateway.cc b/server/core/gateway.cc index 9271ea320..290bb4bbe 100644 --- a/server/core/gateway.cc +++ b/server/core/gateway.cc @@ -2240,15 +2240,15 @@ int main(int argc, char **argv) ss_dassert(worker); worker->run(); - /*< Stop all the monitors */ - monitor_stop_all(); - /** Stop administrative interface */ mxs_admin_shutdown(); - /*< Stop all the monitors */ + /*< Stop all monitors */ monitor_stop_all(); + /*< Destroy all monitors */ + monitor_destroy_all(); + /*< * Wait for the housekeeper to finish. */ diff --git a/server/core/internal/monitor.h b/server/core/internal/monitor.h index 517a9c5e4..52da08da8 100644 --- a/server/core/internal/monitor.h +++ b/server/core/internal/monitor.h @@ -66,6 +66,14 @@ void monitor_deactivate(MXS_MONITOR* monitor); void monitor_stop_all(); void monitor_start_all(); +/** + * @brief Destroys all monitors. At this point all monitors should + * have been stopped. + * + * @attn Must only be called in single-thread context at system shutdown. + */ +void monitor_destroy_all(); + MXS_MONITOR *monitor_find(const char *); MXS_MONITOR* monitor_repurpose_destroyed(const char* name, const char* module); diff --git a/server/core/monitor.cc b/server/core/monitor.cc index 9b30c755a..d79efa813 100644 --- a/server/core/monitor.cc +++ b/server/core/monitor.cc @@ -169,8 +169,6 @@ monitor_destroy(MXS_MONITOR *mon) { MXS_MONITOR *ptr; - mon->api->stopMonitor(mon->instance); - mon->state = MONITOR_STATE_FREED; spinlock_acquire(&monLock); if (allMonitors == mon) { @@ -189,6 +187,8 @@ monitor_destroy(MXS_MONITOR *mon) } } spinlock_release(&monLock); + mon->api->destroyInstance(mon->instance); + mon->state = MONITOR_STATE_FREED; config_parameter_free(mon->parameters); monitor_server_free_all(mon->monitored_servers); MXS_FREE(mon->name); @@ -196,6 +196,18 @@ monitor_destroy(MXS_MONITOR *mon) MXS_FREE(mon); } +void monitor_destroy_all() +{ + // monitor_destroy() grabs 'monLock', so it cannot be grabbed here + // without additional changes. But this function should only be + // called at system shutdown in single-thread context. + + while (allMonitors) + { + MXS_MONITOR *monitor = allMonitors; + monitor_destroy(monitor); + } +} /** * Start an individual monitor that has previously been stopped. @@ -294,18 +306,18 @@ void monitor_deactivate(MXS_MONITOR* monitor) void monitor_stop_all() { - MXS_MONITOR *ptr; - spinlock_acquire(&monLock); - ptr = allMonitors; - while (ptr) + + MXS_MONITOR* monitor = allMonitors; + while (monitor) { - if (ptr->active) + if (monitor->active) { - monitor_stop(ptr); + monitor_stop(monitor); } - ptr = ptr->next; + monitor = monitor->next; } + spinlock_release(&monLock); }