mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-23 00:00:01 +01:00

Just using a standard std::list<> to hold plugins is problematic, because we want to push Plugins to the list from within each Plugin's constructor that is executed during static initialization. Since the order of static initialization is undefined in C++, it may happen that a Plugin constructor is executed before the list could be initialized. Therefore, we use the Nifty Counter Idiom [1] to initialize the list ourself before the first usage. In short: - allocate a buffer for the list - initialize list before first usage - (complicatedly) declaring a buffer is neccessary in order to avoid that the constructor of the static list is executed again
102 lines
3 KiB
C++
102 lines
3 KiB
C++
/** Loadable / plugin support.
|
|
*
|
|
* @file
|
|
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
|
* @author Daniel Krebs <github@daniel-krebs.net>
|
|
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
|
* @license GNU General Public License (version 3)
|
|
*
|
|
* VILLASfpga
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*********************************************************************************/
|
|
|
|
#pragma once
|
|
|
|
#include <list>
|
|
#include <string>
|
|
#include <jansson.h>
|
|
|
|
#include "utils.h"
|
|
|
|
namespace villas {
|
|
|
|
class Plugin {
|
|
public:
|
|
|
|
enum class Type {
|
|
Unknown,
|
|
FpgaIp,
|
|
};
|
|
|
|
Plugin();
|
|
virtual ~Plugin();
|
|
|
|
// each plugin is a singleton, so copying is not allowed
|
|
Plugin(Plugin const&) = delete;
|
|
void operator=(Plugin const&) = delete;
|
|
|
|
int load();
|
|
int unload();
|
|
|
|
virtual int parse(json_t *cfg);
|
|
virtual void dump();
|
|
|
|
/** Find registered and loaded plugin with given name and type. */
|
|
static Plugin *
|
|
lookup(Type type, std::string name);
|
|
|
|
static std::list<Plugin*>
|
|
lookup(Type type);
|
|
|
|
// check if this makes sense! (no intermediate plugins)
|
|
bool
|
|
operator==(const Plugin& other) const;
|
|
|
|
Type pluginType;
|
|
|
|
std::string name;
|
|
std::string description;
|
|
std::string path;
|
|
void *handle;
|
|
|
|
enum state state;
|
|
|
|
private:
|
|
/* Just using a standard std::list<> to hold plugins is problematic, because
|
|
we want to push Plugins to the list from within each Plugin's constructor
|
|
that is executed during static initialization. Since the order of static
|
|
initialization is undefined in C++, it may happen that a Plugin
|
|
constructor is executed before the list could be initialized. Therefore,
|
|
we use the Nifty Counter Idiom [1] to initialize the list ourself before
|
|
the first usage.
|
|
|
|
In short:
|
|
- allocate a buffer for the list
|
|
- initialize list before first usage
|
|
- (complicatedly) declaring a buffer is neccessary in order to avoid
|
|
that the constructor of the static list is executed again
|
|
|
|
[1] https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter
|
|
*/
|
|
|
|
using PluginList = std::list<Plugin *>;
|
|
using PluginListBuffer = typename std::aligned_storage<sizeof (Plugin::PluginList), alignof (Plugin::PluginList)>::type;
|
|
|
|
static PluginListBuffer pluginListBuffer; ///< buffer to hold a PluginList
|
|
static PluginList& pluginList; ///< reference to pluginListBuffer
|
|
static int pluginListNiftyCounter; ///< track if pluginList has been initialized
|
|
};
|
|
|
|
} // namespace villas
|