summaryrefslogtreecommitdiffstats
path: root/upstream/parameter/SystemClass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'upstream/parameter/SystemClass.cpp')
-rw-r--r--upstream/parameter/SystemClass.cpp259
1 files changed, 259 insertions, 0 deletions
diff --git a/upstream/parameter/SystemClass.cpp b/upstream/parameter/SystemClass.cpp
new file mode 100644
index 0000000..21c7a86
--- /dev/null
+++ b/upstream/parameter/SystemClass.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2011-2015, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <algorithm>
+#include "SystemClass.h"
+#include "SubsystemLibrary.h"
+#include "VirtualSubsystem.h"
+#include "LoggingElementBuilderTemplate.h"
+#include <cassert>
+#include "PluginLocation.h"
+#include "DynamicLibrary.hpp"
+#include "Utility.h"
+#include "Memory.hpp"
+
+#define base CConfigurableElement
+
+#ifndef PARAMETER_FRAMEWORK_PLUGIN_ENTRYPOINT_V1
+#error Missing PARAMETER_FRAMEWORK_PLUGIN_ENTRYPOINT_V1 macro definition
+#endif
+#define QUOTE(X) #X
+#define MACRO_TO_STR(X) QUOTE(X)
+const char CSystemClass::entryPointSymbol[] =
+ MACRO_TO_STR(PARAMETER_FRAMEWORK_PLUGIN_ENTRYPOINT_V1);
+using PluginEntryPointV1 = void (*)(CSubsystemLibrary *, core::log::Logger &);
+
+using std::list;
+using std::string;
+
+// FIXME: integrate SystemClass to core namespace
+using namespace core;
+
+CSystemClass::CSystemClass(log::Logger &logger)
+ : _pSubsystemLibrary(new CSubsystemLibrary()), _logger(logger)
+{
+}
+
+CSystemClass::~CSystemClass()
+{
+ delete _pSubsystemLibrary;
+
+ // Destroy child subsystems *before* unloading the libraries (otherwise crashes will occur
+ // as unmapped code will be referenced)
+ clean();
+}
+
+bool CSystemClass::childrenAreDynamic() const
+{
+ return true;
+}
+
+string CSystemClass::getKind() const
+{
+ return "SystemClass";
+}
+
+bool CSystemClass::getMappingData(const std::string & /*strKey*/,
+ const std::string *& /*pStrValue*/) const
+{
+ // Although it could make sense to have mapping in the system class,
+ // just like at subsystem level, it is currently not supported.
+ return false;
+}
+
+string CSystemClass::getFormattedMapping() const
+{
+ return "";
+}
+
+bool CSystemClass::loadSubsystems(string &strError, const CSubsystemPlugins *pSubsystemPlugins,
+ bool bVirtualSubsystemFallback)
+{
+ // Start clean
+ _pSubsystemLibrary->clean();
+
+ typedef TLoggingElementBuilderTemplate<CVirtualSubsystem> VirtualSubsystemBuilder;
+ // Add virtual subsystem builder
+ _pSubsystemLibrary->addElementBuilder("Virtual", new VirtualSubsystemBuilder(_logger));
+ // Set virtual subsytem as builder fallback if required
+ if (bVirtualSubsystemFallback) {
+ _pSubsystemLibrary->setDefaultBuilder(
+ utility::make_unique<VirtualSubsystemBuilder>(_logger));
+ }
+
+ // Add subsystem defined in shared libraries
+ core::Results errors;
+ bool bLoadPluginsSuccess = loadSubsystemsFromSharedLibraries(errors, pSubsystemPlugins);
+
+ // Fill strError for caller, he has to decide if there is a problem depending on
+ // bVirtualSubsystemFallback value
+ strError = utility::asString(errors);
+
+ return bLoadPluginsSuccess || bVirtualSubsystemFallback;
+}
+
+bool CSystemClass::loadSubsystemsFromSharedLibraries(core::Results &errors,
+ const CSubsystemPlugins *pSubsystemPlugins)
+{
+ // Plugin list
+ list<string> lstrPluginFiles;
+
+ size_t pluginLocation;
+
+ for (pluginLocation = 0; pluginLocation < pSubsystemPlugins->getNbChildren();
+ pluginLocation++) {
+
+ // Get Folder for current Plugin Location
+ const CPluginLocation *pPluginLocation =
+ static_cast<const CPluginLocation *>(pSubsystemPlugins->getChild(pluginLocation));
+
+ string strFolder(pPluginLocation->getFolder());
+ if (!strFolder.empty()) {
+ strFolder += "/";
+ }
+ // Iterator on Plugin List:
+ list<string>::const_iterator it;
+
+ const list<string> &pluginList = pPluginLocation->getPluginList();
+
+ for (it = pluginList.begin(); it != pluginList.end(); ++it) {
+
+ // Fill Plugin files list
+ lstrPluginFiles.push_back(strFolder + *it);
+ }
+ }
+
+ // Actually load plugins
+ while (!lstrPluginFiles.empty()) {
+
+ // Because plugins might depend on one another, loading will be done
+ // as an iteration process that finishes successfully when the remaining
+ // list of plugins to load gets empty or unsuccessfully if the loading
+ // process failed to load at least one of them
+
+ // Attempt to load the complete list
+ if (!loadPlugins(lstrPluginFiles, errors)) {
+
+ // Unable to load at least one plugin
+ break;
+ }
+ }
+
+ if (!lstrPluginFiles.empty()) {
+ // Unable to load at least one plugin
+ errors.push_back("Unable to load the following plugins: " +
+ utility::asString(lstrPluginFiles, ", ") + ".");
+ return false;
+ }
+
+ return true;
+}
+
+// Plugin loading
+bool CSystemClass::loadPlugins(list<string> &lstrPluginFiles, core::Results &errors)
+{
+ assert(lstrPluginFiles.size());
+
+ bool bAtLeastOneSubsystemPluginSuccessfullyLoaded = false;
+
+ list<string>::iterator it = lstrPluginFiles.begin();
+
+ while (it != lstrPluginFiles.end()) {
+
+ string strPluginFileName = *it;
+
+ // Load attempt
+ try {
+ auto library = utility::make_unique<DynamicLibrary>(strPluginFileName);
+
+ // Load symbol from library
+ auto subSystemBuilder = library->getSymbol<PluginEntryPointV1>(entryPointSymbol);
+
+ // Store libraries handles
+ _subsystemLibraryHandleList.push_back(std::move(library));
+
+ // Fill library
+ subSystemBuilder(_pSubsystemLibrary, _logger);
+
+ } catch (std::exception &e) {
+ errors.push_back(e.what());
+
+ // Next plugin
+ ++it;
+
+ continue;
+ }
+
+ // Account for this success
+ bAtLeastOneSubsystemPluginSuccessfullyLoaded = true;
+
+ // Remove successfully loaded plugin from list and select next
+ lstrPluginFiles.erase(it++);
+ }
+
+ return bAtLeastOneSubsystemPluginSuccessfullyLoaded;
+}
+
+const CSubsystemLibrary *CSystemClass::getSubsystemLibrary() const
+{
+ return _pSubsystemLibrary;
+}
+
+void CSystemClass::checkForSubsystemsToResync(CSyncerSet &syncerSet, core::Results &infos)
+{
+ size_t uiNbChildren = getNbChildren();
+ size_t uiChild;
+
+ for (uiChild = 0; uiChild < uiNbChildren; uiChild++) {
+
+ CSubsystem *pSubsystem = static_cast<CSubsystem *>(getChild(uiChild));
+
+ // Collect and consume the need for a resync
+ if (pSubsystem->needResync(true)) {
+
+ infos.push_back("Resynchronizing subsystem: " + pSubsystem->getName());
+ // get all subsystem syncers
+ pSubsystem->fillSyncerSet(syncerSet);
+ }
+ }
+}
+
+void CSystemClass::cleanSubsystemsNeedToResync()
+{
+ size_t uiNbChildren = getNbChildren();
+ size_t uiChild;
+
+ for (uiChild = 0; uiChild < uiNbChildren; uiChild++) {
+
+ CSubsystem *pSubsystem = static_cast<CSubsystem *>(getChild(uiChild));
+
+ // Consume the need for a resync
+ pSubsystem->needResync(true);
+ }
+}