text: /*
   * Copyright (c) 2016 MariaDB Corporation Ab
   *
   * Use of this software is governed by the Business Source License included
   * in the LICENSE.TXT file and at www.mariadb.com/bsl11.
   *
   * Change Date: 2025-01-25
   *
   * On the date above, in accordance with the Business Source License, use
   * of this software will be governed by version 2 or later of the General
   * Public License.
   */
  
  #include "maxscale/module.hh"
  #include <maxbase/alloc.h>
  #include <string>
  #include "../../../core/internal/modules.hh"
  
  using std::auto_ptr;
  
  namespace maxscale
  {
  
  mxs::ConfigParameters* Module::create_default_parameters() const
  {
      mxs::ConfigParameters* rval = new mxs::ConfigParameters;
      const MXS_MODULE_PARAM* param_definition = m_module.parameters;
      while (param_definition->name)
      {
          if (param_definition->default_value)
          {
              rval->set(param_definition->name, param_definition->default_value);
          }
          ++param_definition;
      }
      return rval;
  }
  
  //
  // Module
  //
  
  // static
  void* Module::load(const char* zName, const char* zType)
  {
      return load_module(zName, zType);
  }
  
  // static
  const MXS_MODULE* Module::get(const char* zName, const char* zType)
  {
      return get_module(zName, zType);
  }
  
  // static
  bool Module::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;
  }
  
  // static
  void Module::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)();
          }
      }
  }
  
  // static
  bool Module::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;
  }
  
  // static
  void Module::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)();
          }
      }
  }
  }
  