diff options
author | Patrick Benavoli <patrickx.benavoli@intel.com> | 2011-11-20 20:04:35 +0100 |
---|---|---|
committer | David Wagner <david.wagner@intel.com> | 2014-02-10 17:15:01 +0100 |
commit | 9bed7cea60c371df60ab53c2e7ade186f04266f3 (patch) | |
tree | c9ca34c01602ba6628a62ba947a389b86340ee79 | |
parent | ee65e6d992e5fd7c81f62ced1cbed532989c09f7 (diff) | |
download | external_parameter-framework-9bed7cea60c371df60ab53c2e7ade186f04266f3.zip external_parameter-framework-9bed7cea60c371df60ab53c2e7ade186f04266f3.tar.gz external_parameter-framework-9bed7cea60c371df60ab53c2e7ade186f04266f3.tar.bz2 |
PFW: Manage subsystem plugin dependency
BZ: 15204
As subsystem plugins might depend on one another, they can't always be all
loaded at once. Because a certain order must sometimes be respected, the
loading process has now become iterative, not merely failing upon the first
loading failure.
- Fixed a missing carriage return in the configurable domains listing
functionallity
Change-Id: I7e0d6ecbb258fcb1acaad78359e65f0e132d09ab
Signed-off-by: Patrick Benavoli <patrickx.benavoli@intel.com>
Reviewed-on: http://android.intel.com:8080/25408
Reviewed-by: Barthes, FabienX <fabienx.barthes@intel.com>
Tested-by: Barthes, FabienX <fabienx.barthes@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
-rw-r--r-- | parameter/ConfigurableDomains.cpp | 3 | ||||
-rw-r--r-- | parameter/SystemClass.cpp | 164 | ||||
-rw-r--r-- | parameter/SystemClass.h | 10 |
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; |