#include <iterator>
#include <sstream>
-namespace Dali
-{
-namespace Internal
+namespace Dali::Internal
{
AddOnManagerLinux::AddOnManagerLinux() = default;
-AddOnManagerLinux::~AddOnManagerLinux() = default;
+AddOnManagerLinux::~AddOnManagerLinux()
+{
+ // Close all the libraries
+ for(auto& addon : mAddOnCache)
+ {
+ if(addon.libHandle)
+ {
+ dlclose(addon.libHandle);
+ }
+ }
+}
void AddOnManagerLinux::RegisterAddOnDispatchTable(const AddOnDispatchTable* dispatchTable)
{
fullPath += "/";
fullPath += name;
+ // Get cache count before we load the library to ensure the library does indeed load an addon
+ const auto cacheCountBeforeLibraryLoad = mAddOnCache.size();
+
// open lib, look for essential symbols. The libary is opened with RTLD_DEEPBIND flag
// to make sure the local symbol table is going to be used during lookup first.
auto* handle = dlopen(fullPath.c_str(), RTLD_DEEPBIND | RTLD_LAZY);
if(handle)
{
- DALI_ASSERT_ALWAYS(!mAddOnCache.empty() && "AddOnCache should not be empty!");
-
- auto& cacheEntry = mAddOnCache.back();
- AddOnInfo info{};
- cacheEntry.GetAddOnInfo(info);
- cacheEntry.info = info;
- cacheEntry.addOnLib = fullPath;
- cacheEntry.libHandle = handle;
- cacheEntry.opened = false;
+ // Addon Cache size should have increased by 1
+ const auto cacheCountAfterLibraryLoad = mAddOnCache.size();
+ if((cacheCountBeforeLibraryLoad + 1) == cacheCountAfterLibraryLoad)
+ {
+ auto& cacheEntry = mAddOnCache.back();
+ AddOnInfo info{};
+ cacheEntry.GetAddOnInfo(info);
+ cacheEntry.info = info;
+ cacheEntry.addOnLib = fullPath;
+ cacheEntry.libHandle = handle;
+ cacheEntry.opened = false;
+ }
+ else
+ {
+ DALI_LOG_ERROR("Can't find any addon in %s library\n", fullPath.c_str());
+ }
}
else
{
}
else
{
+ // Get cache count before we load the library to ensure the library does indeed load an addon
+ const auto cacheCountBeforeLibraryLoad = mAddOnCache.size();
+
// Attempt to load the library if not found in the cache
auto* handle = dlopen(libraryName.c_str(), RTLD_DEEPBIND | RTLD_LAZY);
if(handle)
{
- // Can only have one addon per library so just check if the last added item to the cache is the addon we want
- DALI_ASSERT_ALWAYS(!mAddOnCache.empty() && "AddOnCache should not be empty!");
-
- auto& cacheEntry = mAddOnCache.back();
- AddOnInfo info{};
- cacheEntry.GetAddOnInfo(info);
- if(info.name == addonName)
+ // Addon Cache size should have increased by 1
+ const auto cacheCountAfterLibraryLoad = mAddOnCache.size();
+ if((cacheCountBeforeLibraryLoad + 1) == cacheCountAfterLibraryLoad)
{
- cacheEntry.info = info;
- cacheEntry.addOnLib = libraryName;
- cacheEntry.libHandle = handle;
- cacheEntry.opened = true;
- addOnLibrary = reinterpret_cast<void*>(mAddOnCache.size());
+ // Can only have one addon per library so just check if the last added item to the cache is the addon we want
+ auto& cacheEntry = mAddOnCache.back();
+ AddOnInfo info{};
+ cacheEntry.GetAddOnInfo(info);
+ if(info.name == addonName)
+ {
+ cacheEntry.info = info;
+ cacheEntry.addOnLib = libraryName;
+ cacheEntry.libHandle = handle;
+ cacheEntry.opened = true;
+ addOnLibrary = reinterpret_cast<void*>(cacheCountAfterLibraryLoad);
+ }
}
- else
+
+ if(!addOnLibrary)
{
DALI_LOG_ERROR("Can't find %s addon in %s library\n", addonName.c_str(), libraryName.c_str());
}
void* AddOnManagerLinux::GetGlobalProc(const Dali::AddOnLibrary& addonHandle, const char* procName)
{
- if(!addonHandle)
+ auto index = (intptr_t(addonHandle));
+ if(index < 1 && index > static_cast<intptr_t>(mAddOnCache.size()))
{
+ DALI_LOG_ERROR("Invalid AddOn handle!\n");
return nullptr;
}
- auto index = (intptr_t(addonHandle));
- DALI_ASSERT_ALWAYS(index >= 1 && index <= static_cast<intptr_t>(mAddOnCache.size()) && "Invalid AddOn handle!");
-
const auto& entry = mAddOnCache[index - 1];
-
if(entry.opened && entry.libHandle)
{
// First call into dispatch table
}
return retval;
}
- else
- {
- DALI_LOG_ERROR("AddOn: GetGlobalProc() library failed!\n");
- }
+
+ DALI_LOG_ERROR("AddOn: GetGlobalProc() library failed!\n");
return nullptr;
}
void* AddOnManagerLinux::GetInstanceProc(const Dali::AddOnLibrary& addonHandle, const char* procName)
{
- if(!addonHandle)
+ auto index = (intptr_t(addonHandle));
+ if(index < 1 && index > static_cast<intptr_t>(mAddOnCache.size()))
{
+ DALI_LOG_ERROR("Invalid AddOn handle!\n");
return nullptr;
}
- auto index = (intptr_t(addonHandle));
- DALI_ASSERT_ALWAYS(index >= 1 && index <= static_cast<intptr_t>(mAddOnCache.size()) && "Invalid AddOn handle!");
-
const auto& entry = mAddOnCache[index - 1];
if(entry.opened && entry.libHandle)
{
}
return retval;
}
+
+ DALI_LOG_ERROR("AddOn: GetInstanceProc() library failed!\n");
return nullptr;
}
}
}
-} // namespace Internal
-} // namespace Dali
\ No newline at end of file
+} // namespace Dali::Internal
\ No newline at end of file