summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--parameter/ConfigurableDomains.cpp3
-rw-r--r--parameter/SystemClass.cpp164
-rw-r--r--parameter/SystemClass.h10
3 files changed, 119 insertions, 58 deletions
diff --git a/parameter/ConfigurableDomains.cpp b/parameter/ConfigurableDomains.cpp
index 597d453..d021d8c 100644
--- a/parameter/ConfigurableDomains.cpp
+++ b/parameter/ConfigurableDomains.cpp
@@ -381,8 +381,9 @@ void CConfigurableDomains::listDomains(string& strResult) const
// Sequence awareness
if (pChildConfigurableDomain->getSequenceAwareness()) {
- strResult += " [sequence aware]\n";
+ strResult += " [sequence aware]";
}
+ strResult += "\n";
}
}
diff --git a/parameter/SystemClass.cpp b/parameter/SystemClass.cpp
index 97fc89f..532473a 100644
--- a/parameter/SystemClass.cpp
+++ b/parameter/SystemClass.cpp
@@ -37,6 +37,7 @@
#include "AutoLog.h"
#include "VirtualSubsystem.h"
#include "NamedElementBuilderTemplate.h"
+#include <assert.h>
#define base CConfigurableElement
@@ -80,7 +81,7 @@ bool CSystemClass::loadSubsystems(string& strError, const vector<string>& astrPl
CAutoLog autoLlog(this, "Loading subsystem plugins");
// Plugin list
- vector<string> astrPluginFiles;
+ list<string> lstrPluginFiles;
uint32_t uiFolderLocation;
@@ -90,77 +91,40 @@ bool CSystemClass::loadSubsystems(string& strError, const vector<string>& astrPl
string strPluginPath = astrPluginFolderPaths[uiFolderLocation] + "/";
// Get plugin list
- getPluginFiles(strPluginPath, astrPluginFiles);
+ getPluginFiles(strPluginPath, lstrPluginFiles);
}
// Check at least one subsystem plugin available
- if (!astrPluginFiles.size()) {
+ if (!lstrPluginFiles.size()) {
// No plugin found?
- strError = "No subsystem plugin found";
+ log("No subsystem plugin found");
- return false;
+ // Don't bail out now that we have virtual subsystems
}
- // Actually load plugins
- uint32_t uiPlugin;
// Start clean
_pSubsystemLibrary->clean();
- for (uiPlugin = 0; uiPlugin < astrPluginFiles.size(); uiPlugin++) {
-
- string strPluginFileName = astrPluginFiles[uiPlugin];
-
- log("Loading subsystem plugin path \"%s\"", strPluginFileName.c_str());
-
- void* lib_handle = dlopen(strPluginFileName.c_str(), RTLD_LAZY);
-
- if (!lib_handle) {
-
- // Return error
- const char* pcError = dlerror();
-
- if (pcError) {
-
- strError = pcError;
- } else {
-
- strError = "Unable to load subsystem plugin " + strPluginFileName;
- }
-
- _pSubsystemLibrary->clean();
-
- return false;
- }
-
- // Extract plugin type out of file name
- string strPluginPattern = gpcPluginPattern;
- string strLibraryPrefix = gpcLibraryPrefix;
- // Remove folder
- int32_t iSlashPos = strPluginFileName.rfind('/') + 1 + strLibraryPrefix.length();
- // Get type
- string strPluginType = strPluginFileName.substr(iSlashPos, strPluginFileName.length() - iSlashPos - strPluginPattern.length());
-
- // Make it upper case
- std::transform(strPluginType.begin(), strPluginType.end(), strPluginType.begin(), ::toupper);
-
- // Get plugin symbol
- string strPluginSymbol = gpcPluginSymbolPrefix + strPluginType + gpcPluginSymbolSuffix;
+ // Actually load plugins
+ while (lstrPluginFiles.size()) {
- // Load symbol from library
- GetSusbystemBuilder pfnGetSusbystemBuilder = (GetSusbystemBuilder)dlsym(lib_handle, strPluginSymbol.c_str());
+ // 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
- if (!pfnGetSusbystemBuilder) {
+ // Attempt to load the complete list
+ if (!loadPlugins(lstrPluginFiles, strError)) {
- strError = "Subsystem plugin " + strPluginFileName + " does not contain " + strPluginSymbol + " symbol.";
+ // Display the list of plugins we were unable to load
+ // Leave clean
_pSubsystemLibrary->clean();
return false;
}
-
- // Fill library
- pfnGetSusbystemBuilder(_pSubsystemLibrary);
}
+ log("All subsystem plugins successfully loaded");
// Add virtual subsystem builder
_pSubsystemLibrary->addElementBuilder(new TNamedElementBuilderTemplate<CVirtualSubsystem>("Virtual"));
@@ -168,7 +132,8 @@ bool CSystemClass::loadSubsystems(string& strError, const vector<string>& astrPl
return true;
}
-bool CSystemClass::getPluginFiles(const string& strPluginPath, vector<string>& astrPluginFiles) const
+// Subsystem plugins
+bool CSystemClass::getPluginFiles(const string& strPluginPath, list<string>& lstrPluginFiles) const
{
log("Seeking subsystem plugins from folder \"%s\"", strPluginPath.c_str());
@@ -192,7 +157,7 @@ bool CSystemClass::getPluginFiles(const string& strPluginPath, vector<string>& a
if (uiPatternPos != (size_t)-1 && uiPatternPos == strFileName.size() - strPluginPattern.size()) {
// Found plugin
- astrPluginFiles.push_back(strPluginPath + strFileName);
+ lstrPluginFiles.push_back(strPluginPath + strFileName);
}
}
@@ -202,6 +167,95 @@ bool CSystemClass::getPluginFiles(const string& strPluginPath, vector<string>& a
return true;
}
+// Plugin symbol computation
+string CSystemClass::getPluginSymbol(const string& strPluginPath)
+{
+ // Extract plugin type out of file name
+ string strPluginPattern = gpcPluginPattern;
+ string strLibraryPrefix = gpcLibraryPrefix;
+
+ // Remove folder
+ int32_t iSlashPos = strPluginPath.rfind('/') + 1 + strLibraryPrefix.length();
+
+ // Get type
+ string strPluginType = strPluginPath.substr(iSlashPos, strPluginPath.length() - iSlashPos - strPluginPattern.length());
+
+ // Make it upper case
+ std::transform(strPluginType.begin(), strPluginType.end(), strPluginType.begin(), ::toupper);
+
+ // Get plugin symbol
+ return gpcPluginSymbolPrefix + strPluginType + gpcPluginSymbolSuffix;
+}
+
+// Plugin loading
+bool CSystemClass::loadPlugins(list<string>& lstrPluginFiles, string& strError)
+{
+ assert(lstrPluginFiles.size());
+
+ bool bAtLeastOneSybsystemPluginSuccessfullyLoaded = false;
+
+ list<string>::iterator it = lstrPluginFiles.begin();
+
+ while (it != lstrPluginFiles.end()) {
+
+ string strPluginFileName = *it;
+
+ log("Attempting to load subsystem plugin path \"%s\"", strPluginFileName.c_str());
+
+ // Load attempt
+ void* lib_handle = dlopen(strPluginFileName.c_str(), RTLD_LAZY);
+
+ if (!lib_handle) {
+
+ // Failed
+ log("Plugin load failed, proceeding on with remaining ones");
+
+ // Next plugin
+ ++it;
+
+ continue;
+ }
+
+ // Get plugin symbol
+ string strPluginSymbol = getPluginSymbol(strPluginFileName);
+
+ // Load symbol from library
+ GetSusbystemBuilder pfnGetSusbystemBuilder = (GetSusbystemBuilder)dlsym(lib_handle, strPluginSymbol.c_str());
+
+ if (!pfnGetSusbystemBuilder) {
+
+ strError = "Subsystem plugin " + strPluginFileName + " does not contain " + strPluginSymbol + " symbol.";
+
+ return false;
+ }
+
+ // Fill library
+ pfnGetSusbystemBuilder(_pSubsystemLibrary);
+
+ // Account for this success
+ bAtLeastOneSybsystemPluginSuccessfullyLoaded = true;
+
+ // Remove successfully loaded plugin from list and select next
+ lstrPluginFiles.erase(it++);
+ }
+
+ // Check for success
+ if (!bAtLeastOneSybsystemPluginSuccessfullyLoaded) {
+
+ // Return list of plugins we were unable to load
+ strError = "Unable to load the following plugins:\n";
+
+ for (it = lstrPluginFiles.begin(); it != lstrPluginFiles.end(); ++it) {
+
+ strError += *it + "\n";
+ }
+
+ return false;
+ }
+
+ return true;
+}
+
const CSubsystemLibrary* CSystemClass::getSubsystemLibrary() const
{
return _pSubsystemLibrary;
diff --git a/parameter/SystemClass.h b/parameter/SystemClass.h
index d80ab52..512c5ec 100644
--- a/parameter/SystemClass.h
+++ b/parameter/SystemClass.h
@@ -31,7 +31,7 @@
#pragma once
#include "ConfigurableElement.h"
-#include <vector>
+#include <list>
class CSubsystemLibrary;
@@ -54,7 +54,13 @@ private:
virtual bool childrenAreDynamic() const;
// Subsystem plugins
- bool getPluginFiles(const string& strPluginPath, vector<string>& astrPluginFiles) const;
+ bool getPluginFiles(const string& strPluginPath, list<string>& lstrPluginFiles) const;
+
+ // Plugin symbol computation
+ static string getPluginSymbol(const string& strPluginPath);
+
+ // Plugin loading
+ bool loadPlugins(list<string>& lstrPluginFiles, string& strError);
// ref only
CSubsystemLibrary* _pSubsystemLibrary;