Call [process|thread] [init|finish] functions of modules

The process initialization function was also renamed from init to
process_init.
This commit is contained in:
Johan Wikman
2017-01-05 16:17:50 +02:00
parent a2a38f952a
commit 03391748ee
2 changed files with 168 additions and 11 deletions

View File

@ -120,13 +120,13 @@ typedef struct mxs_module
* *
* @return 0 on success, non-zero on failure. * @return 0 on success, non-zero on failure.
*/ */
int (*init)(); int (*process_init)();
/** /**
* If non-NULL, this function is called once at process shutdown, provided * If non-NULL, this function is called once at process shutdown, provided
* the call to @c init succeeded. * the call to @c init succeeded.
*/ */
void (*finish)(); void (*process_finish)();
/** /**
* If non-NULL, this function is called once at the startup of every new thread. * If non-NULL, this function is called once at the startup of every new thread.

View File

@ -185,6 +185,10 @@ static bool change_cwd();
static void log_exit_status(); static void log_exit_status();
static bool daemonize(); static bool daemonize();
static bool sniff_configuration(const char* filepath); static bool sniff_configuration(const char* filepath);
static bool modules_process_init();
static void modules_process_finish();
static bool modules_thread_init();
static void modules_thread_finish();
/** SSL multi-threading functions and structures */ /** SSL multi-threading functions and structures */
@ -970,6 +974,8 @@ static void usage(void)
*/ */
void worker_thread_main(void* arg) void worker_thread_main(void* arg)
{ {
if (modules_thread_init())
{
if (qc_thread_init()) if (qc_thread_init())
{ {
/** Init mysql thread context for use with a mysql handle and a parser */ /** Init mysql thread context for use with a mysql handle and a parser */
@ -991,6 +997,13 @@ void worker_thread_main(void* arg)
{ {
MXS_ERROR("Could not perform thread initialization for query classifier. Exiting thread."); MXS_ERROR("Could not perform thread initialization for query classifier. Exiting thread.");
} }
modules_thread_finish();
}
else
{
MXS_ERROR("Could not perform thread initialization for all modules. Thread exits.");
}
} }
/** /**
@ -1945,6 +1958,15 @@ int main(int argc, char **argv)
poll_init(); poll_init();
dcb_global_init(); dcb_global_init();
/* Init MaxScale modules */
if (!modules_process_init())
{
MXS_ERROR("Failed to initialize all modules at startup. Exiting.");
rc = MAXSCALE_BADCONFIG;
goto return_main;
}
/** /**
* Init mysql thread context for main thread as well. Needed when users * Init mysql thread context for main thread as well. Needed when users
* are queried from backends. * are queried from backends.
@ -2058,6 +2080,9 @@ int main(int argc, char **argv)
/*< Stop all the monitors */ /*< Stop all the monitors */
monitorStopAll(); monitorStopAll();
/*< Call finish on all modules. */
modules_process_finish();
log_exit_status(); log_exit_status();
MXS_NOTICE("MaxScale is shutting down."); MXS_NOTICE("MaxScale is shutting down.");
/** Release mysql thread context*/ /** Release mysql thread context*/
@ -2807,3 +2832,135 @@ static bool sniff_configuration(const char* filepath)
return rv == 0; return rv == 0;
} }
/**
* Calls init on all loaded modules.
*
* @return True, if all modules were successfully initialized.
*/
static bool modules_process_init()
{
bool initialized = false;
MXS_MODULE_ITERATOR i = mxs_module_iterator_get(NULL);
MXS_MODULE* module = NULL;
while ((module = mxs_module_iterator_get_next(&i)) != NULL)
{
if (module->process_init)
{
int rc = (module->process_init)();
if (rc != 0)
{
break;
}
}
}
if (module)
{
// If module is non-NULL it means that the initialization failed for
// that module. We now need to call finish on all modules that were
// successfully initialized.
MXS_MODULE* failed_module = module;
i = mxs_module_iterator_get(NULL);
while ((module = mxs_module_iterator_get_next(&i)) != failed_module)
{
if (module->process_finish)
{
(module->process_finish)();
}
}
}
else
{
initialized = true;
}
return initialized;
}
/**
* Calls process_finish on all loaded modules.
*/
static void modules_process_finish()
{
MXS_MODULE_ITERATOR i = mxs_module_iterator_get(NULL);
MXS_MODULE* module = NULL;
while ((module = mxs_module_iterator_get_next(&i)) != NULL)
{
if (module->process_finish)
{
(module->process_finish)();
}
}
}
/**
* Calls thread_init on all loaded modules.
*
* @return True, if all modules were successfully initialized.
*/
static bool modules_thread_init()
{
bool initialized = false;
MXS_MODULE_ITERATOR i = mxs_module_iterator_get(NULL);
MXS_MODULE* module = NULL;
while ((module = mxs_module_iterator_get_next(&i)) != NULL)
{
if (module->thread_init)
{
int rc = (module->thread_init)();
if (rc != 0)
{
break;
}
}
}
if (module)
{
// If module is non-NULL it means that the initialization failed for
// that module. We now need to call finish on all modules that were
// successfully initialized.
MXS_MODULE* failed_module = module;
i = mxs_module_iterator_get(NULL);
while ((module = mxs_module_iterator_get_next(&i)) != failed_module)
{
if (module->thread_finish)
{
(module->thread_finish)();
}
}
}
else
{
initialized = true;
}
return initialized;
}
/**
* Calls thread_finish on all loaded modules.
*/
static void modules_thread_finish()
{
MXS_MODULE_ITERATOR i = mxs_module_iterator_get(NULL);
MXS_MODULE* module = NULL;
while ((module = mxs_module_iterator_get_next(&i)) != NULL)
{
if (module->thread_finish)
{
(module->thread_finish)();
}
}
}