diff --git a/server/core/dcb.cc b/server/core/dcb.cc index de0572e6d..a3567a391 100644 --- a/server/core/dcb.cc +++ b/server/core/dcb.cc @@ -56,6 +56,7 @@ #include "internal/modules.h" #include "internal/session.h" +#include "internal/service.hh" using maxscale::RoutingWorker; using maxbase::Worker; @@ -218,6 +219,11 @@ DCB* dcb_alloc(dcb_role_t role, SERV_LISTENER* listener) newdcb->poll.owner = RoutingWorker::get_current(); } + if (role == DCB_ROLE_CLIENT_HANDLER) + { + mxb::atomic::add(&listener->service->client_count, 1, mxb::atomic::RELAXED); + } + return newdcb; } @@ -282,6 +288,21 @@ void dcb_free_all_memory(DCB* dcb) this_thread.current_dcb = NULL; } + if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER) + { + Service* service = static_cast(dcb->service); + 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 + mxs::RoutingWorker* main_worker = mxs::RoutingWorker::get(mxs::RoutingWorker::MAIN); + main_worker->execute([service]() { + service_free(service); + }, Worker::EXECUTE_AUTO); + } + } + DCB_CALLBACK* cb_dcb; if (dcb->protocol) @@ -2518,7 +2539,7 @@ DCB* dcb_accept(DCB* dcb) } if (client_dcb->service->max_connections - && client_dcb->service->client_count >= client_dcb->service->max_connections) + && client_dcb->service->client_count > client_dcb->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 16b7c0654..d541f88be 100644 --- a/server/core/session.cc +++ b/server/core/session.cc @@ -336,23 +336,6 @@ void session_close(MXS_SESSION* session) } } -class ServiceDestroyTask : public Worker::DisposableTask -{ -public: - ServiceDestroyTask(Service* service) - : m_service(service) - { - } - - void execute(Worker& worker) override - { - service_free(m_service); - } - -private: - Service* m_service; -}; - /** * Deallocate the specified session * @@ -1253,7 +1236,6 @@ Session::Session(SERVICE* service) 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() @@ -1271,17 +1253,6 @@ 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 - mxs::RoutingWorker* main_worker = mxs::RoutingWorker::get(mxs::RoutingWorker::MAIN); - main_worker->execute( - std::unique_ptr(new ServiceDestroyTask(static_cast(service))), - Worker::EXECUTE_AUTO); - } } namespace diff --git a/server/core/test/test_poll.cc b/server/core/test/test_poll.cc index 910fd536a..9031b04c1 100644 --- a/server/core/test/test_poll.cc +++ b/server/core/test/test_poll.cc @@ -53,6 +53,7 @@ static int test1() SERVICE service; service.routerModule = (char*)"required by a check in dcb.cc"; + dummy.service = &service; /* Poll tests */ fprintf(stderr,