From a27bec5e8874e018a52d66e874e798b515b09773 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Fri, 21 Apr 2017 19:57:45 +0300 Subject: [PATCH] Add return value to Worker::init() Cleaner to return status than exit upon failure. --- server/core/gateway.cc | 29 ++++------------ server/core/maxscale/worker.hh | 4 ++- server/core/worker.cc | 61 ++++++++++++++++++++++------------ 3 files changed, 50 insertions(+), 44 deletions(-) diff --git a/server/core/gateway.cc b/server/core/gateway.cc index 4989acc47..9d53c128c 100644 --- a/server/core/gateway.cc +++ b/server/core/gateway.cc @@ -12,27 +12,7 @@ */ /** - * @file gateway.c - The gateway entry point. - * - * @verbatim - * Revision History - * - * Date Who Description - * 23-05-2013 Massimiliano Pinto epoll loop test - * 12-06-2013 Mark Riddoch Add the -p option to set the - * listening port - * and bind addr is 0.0.0.0 - * 19/06/13 Mark Riddoch Extract the epoll functionality - * 21/06/13 Mark Riddoch Added initial config support - * 27/06/13 - * 28/06/13 Vilho Raatikka Added necessary headers, example functions and - * calls to log manager and to query classifier. - * Put example code behind SS_DEBUG macros. - * 05/02/14 Mark Riddoch Addition of version string - * 29/06/14 Massimiliano Pinto Addition of pidfile - * 10/08/15 Markus Makela Added configurable directory locations - * 19/01/16 Markus Makela Set cwd to log directory - * @endverbatim + * @file gateway.c - The entry point of MaxScale */ #include @@ -1910,7 +1890,12 @@ int main(int argc, char **argv) goto return_main; } - Worker::init(); + if (!Worker::init()) + { + MXS_ERROR("Failed to initialize workers."); + rc = MAXSCALE_INTERNALERROR; + goto return_main; + } /* Init MaxScale modules */ if (!modules_process_init()) diff --git a/server/core/maxscale/worker.hh b/server/core/maxscale/worker.hh index 48b19a486..8d93b99fb 100644 --- a/server/core/maxscale/worker.hh +++ b/server/core/maxscale/worker.hh @@ -75,8 +75,10 @@ public: * * To be called once at process startup. This will cause as many workers * to be created as the number of threads defined. + * + * @return True if the initialization succeeded, false otherwise. */ - static void init(); + static bool init(); /** * Finalize the worker mechanism. diff --git a/server/core/worker.cc b/server/core/worker.cc index 52ac58e84..54e46a9f6 100644 --- a/server/core/worker.cc +++ b/server/core/worker.cc @@ -39,6 +39,7 @@ namespace */ static struct this_unit { + bool initialized; // Whether the initialization has been performed. int n_workers; // How many workers there are. Worker** ppWorkers; // Array of worker instances. int number_poll_spins; // Maximum non-block polls @@ -46,8 +47,11 @@ static struct this_unit } this_unit = { + false, 0, - NULL + NULL, + 0, + 0 }; static thread_local struct this_thread @@ -154,47 +158,62 @@ Worker::~Worker() } // static -void Worker::init() +bool Worker::init() { + ss_dassert(!this_unit.initialized); + this_unit.n_workers = config_threadcount(); this_unit.number_poll_spins = config_nbpolls(); this_unit.max_poll_sleep = config_pollsleep(); - this_unit.ppWorkers = new (std::nothrow) Worker* [this_unit.n_workers] (); // Zero initialized array - if (!this_unit.ppWorkers) + if (this_unit.ppWorkers) { - // If we cannot allocate the array, we just exit. - exit(-1); - } - - for (int i = 0; i < this_unit.n_workers; ++i) - { - Worker* pWorker = Worker::create(i); - - if (pWorker) + for (int i = 0; i < this_unit.n_workers; ++i) { - this_unit.ppWorkers[i] = pWorker; - } - else - { - // If a worker cannot be created, we just exit. No way we can continue. - exit(-1); + Worker* pWorker = Worker::create(i); + + if (pWorker) + { + this_unit.ppWorkers[i] = pWorker; + } + else + { + for (int j = i - 1; j >= 0; --j) + { + delete this_unit.ppWorkers[j]; + } + + delete this_unit.ppWorkers; + this_unit.ppWorkers = NULL; + break; + } + + if (this_unit.ppWorkers) + { + this_unit.initialized = true; + } } } - MXS_NOTICE("Workers created!"); + return this_unit.initialized; } void Worker::finish() { - for (int i = 0; i < this_unit.n_workers; ++i) + ss_dassert(this_unit.initialized); + + for (int i = this_unit.n_workers - 1; i >= 0; --i) { Worker* pWorker = this_unit.ppWorkers[i]; delete pWorker; this_unit.ppWorkers[i] = NULL; } + + delete [] this_unit.ppWorkers; + this_unit.ppWorkers = NULL; + this_unit.initialized = false; } namespace