diff --git a/server/core/listener.cc b/server/core/listener.cc index c63008943..34d599eae 100644 --- a/server/core/listener.cc +++ b/server/core/listener.cc @@ -855,7 +855,7 @@ DCB* Listener::accept_one_dcb(int fd, const sockaddr_storage* addr, const char* return NULL; } - if (m_service->max_connections && m_service->client_count >= m_service->max_connections) + if (m_service->max_connections && m_service->client_count > m_service->max_connections) { // TODO: If connections can be queued, this is the place to put the // TODO: connection on that queue. diff --git a/server/core/session.cc b/server/core/session.cc index 14af334fa..40170d50f 100644 --- a/server/core/session.cc +++ b/server/core/session.cc @@ -1134,6 +1134,7 @@ Session::Session(const SListener& listener) mxb::atomic::add(&service->stats.n_current, 1, mxb::atomic::RELAXED); mxb_assert(service->stats.n_current >= 0); + mxb::atomic::add(&service->client_count, 1, mxb::atomic::RELAXED); } Session::~Session() @@ -1151,6 +1152,17 @@ Session::~Session() mxb::atomic::add(&service->stats.n_current, -1, mxb::atomic::RELAXED); mxb_assert(service->stats.n_current >= 0); + bool should_destroy = !mxb::atomic::load(&service->active); + + if (mxb::atomic::add(&service->client_count, -1) == 1 && should_destroy) + { + // Destroy the service in the main routing worker thread + auto svc = static_cast(service); + mxs::RoutingWorker* main_worker = mxs::RoutingWorker::get(mxs::RoutingWorker::MAIN); + main_worker->execute([svc]() { + service_free(svc); + }, Worker::EXECUTE_AUTO); + } } void Session::set_client_dcb(DCB* dcb)