Add return value to Worker::init()

Cleaner to return status than exit upon failure.
This commit is contained in:
Johan Wikman
2017-04-21 19:57:45 +03:00
parent adb2cc1517
commit a27bec5e88
3 changed files with 50 additions and 44 deletions

View File

@ -12,27 +12,7 @@
*/ */
/** /**
* @file gateway.c - The gateway entry point. * @file gateway.c - The entry point of MaxScale
*
* @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
*/ */
#include <maxscale/cdefs.h> #include <maxscale/cdefs.h>
@ -1910,7 +1890,12 @@ int main(int argc, char **argv)
goto return_main; goto return_main;
} }
Worker::init(); if (!Worker::init())
{
MXS_ERROR("Failed to initialize workers.");
rc = MAXSCALE_INTERNALERROR;
goto return_main;
}
/* Init MaxScale modules */ /* Init MaxScale modules */
if (!modules_process_init()) if (!modules_process_init())

View File

@ -75,8 +75,10 @@ public:
* *
* To be called once at process startup. This will cause as many workers * To be called once at process startup. This will cause as many workers
* to be created as the number of threads defined. * 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. * Finalize the worker mechanism.

View File

@ -39,6 +39,7 @@ namespace
*/ */
static struct this_unit static struct this_unit
{ {
bool initialized; // Whether the initialization has been performed.
int n_workers; // How many workers there are. int n_workers; // How many workers there are.
Worker** ppWorkers; // Array of worker instances. Worker** ppWorkers; // Array of worker instances.
int number_poll_spins; // Maximum non-block polls int number_poll_spins; // Maximum non-block polls
@ -46,8 +47,11 @@ static struct this_unit
} this_unit = } this_unit =
{ {
false,
0, 0,
NULL NULL,
0,
0
}; };
static thread_local struct this_thread static thread_local struct this_thread
@ -154,47 +158,62 @@ Worker::~Worker()
} }
// static // static
void Worker::init() bool Worker::init()
{ {
ss_dassert(!this_unit.initialized);
this_unit.n_workers = config_threadcount(); this_unit.n_workers = config_threadcount();
this_unit.number_poll_spins = config_nbpolls(); this_unit.number_poll_spins = config_nbpolls();
this_unit.max_poll_sleep = config_pollsleep(); this_unit.max_poll_sleep = config_pollsleep();
this_unit.ppWorkers = new (std::nothrow) Worker* [this_unit.n_workers] (); // Zero initialized array 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. for (int i = 0; i < this_unit.n_workers; ++i)
exit(-1);
}
for (int i = 0; i < this_unit.n_workers; ++i)
{
Worker* pWorker = Worker::create(i);
if (pWorker)
{ {
this_unit.ppWorkers[i] = pWorker; Worker* pWorker = Worker::create(i);
}
else if (pWorker)
{ {
// If a worker cannot be created, we just exit. No way we can continue. this_unit.ppWorkers[i] = pWorker;
exit(-1); }
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() 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]; Worker* pWorker = this_unit.ppWorkers[i];
delete pWorker; delete pWorker;
this_unit.ppWorkers[i] = NULL; this_unit.ppWorkers[i] = NULL;
} }
delete [] this_unit.ppWorkers;
this_unit.ppWorkers = NULL;
this_unit.initialized = false;
} }
namespace namespace