tahoma2d/toonz/sources/common/tsystem/tpluginmanager.cpp

228 lines
5.6 KiB
C++
Raw Normal View History

2016-03-19 06:57:51 +13:00
#include "tpluginmanager.h"
#include "tsystem.h"
#include "tconvert.h"
#include "tlogger.h"
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-03-19 06:57:51 +13:00
#include <windows.h>
#else
// QUALE DI QUESTI SERVE VERAMENTE??
#include <grp.h>
#include <utime.h>
#include <sys/param.h>
#include <unistd.h>
#include <sys/types.h>
2016-06-15 18:43:10 +12:00
#include <sys/timeb.h> // for ftime
2016-03-19 06:57:51 +13:00
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/dir.h>
2016-06-15 18:43:10 +12:00
#include <sys/param.h> // for getfsstat
2016-03-27 13:44:21 +13:00
#ifdef MACOSX
2016-03-19 06:57:51 +13:00
#include <sys/ucred.h>
2016-03-27 13:44:21 +13:00
#endif
2016-03-19 06:57:51 +13:00
#include <sys/mount.h>
#include <pwd.h>
#include <dlfcn.h>
#endif
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
class TPluginManager::Plugin {
2016-03-19 06:57:51 +13:00
public:
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-06-15 18:43:10 +12:00
typedef HINSTANCE Handle;
2016-03-19 06:57:51 +13:00
#else
2016-06-15 18:43:10 +12:00
typedef void *Handle;
2016-03-19 06:57:51 +13:00
#endif
private:
2016-06-15 18:43:10 +12:00
Handle m_handle;
TPluginInfo m_info;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
Plugin(Handle handle) : m_handle(handle) {}
Handle getHandle() const { return m_handle; }
const TPluginInfo &getInfo() const { return m_info; }
void setInfo(const TPluginInfo &info) { m_info = info; }
std::string getName() const { return m_info.getName(); }
2016-03-19 06:57:51 +13:00
};
//-----------------------------------------------------------------------------
typedef const TPluginInfo *TnzLibMainProcType();
//--------------------------------------------------------------
2016-06-15 18:43:10 +12:00
namespace {
2016-03-19 06:57:51 +13:00
const char *TnzLibMainProcName = "TLibMain";
2016-04-15 17:11:23 +12:00
#if !defined(_WIN32)
2016-03-19 06:57:51 +13:00
const char *TnzLibMainProcName2 = "_TLibMain";
#endif
}
//=============================================================================
2016-06-15 18:43:10 +12:00
TPluginManager::TPluginManager() { m_ignoreList.insert("tnzimagevector"); }
2016-03-19 06:57:51 +13:00
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TPluginManager::~TPluginManager() {
// try { unloadPlugins(); } catch(...) {}
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TPluginManager *TPluginManager::instance() {
static TPluginManager _instance;
return &_instance;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
bool TPluginManager::isIgnored(std::string name) const {
return m_ignoreList.count(toLower(name)) > 0;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TPluginManager::unloadPlugins() {
for (PluginTable::iterator it = m_pluginTable.begin();
it != m_pluginTable.end(); ++it) {
Plugin::Handle handle = (*it)->getHandle();
2016-03-19 06:57:51 +13:00
#ifndef LINUX
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-06-15 18:43:10 +12:00
FreeLibrary(handle);
2016-03-19 06:57:51 +13:00
#else
2016-06-15 18:43:10 +12:00
dlclose(handle);
2016-03-19 06:57:51 +13:00
#endif
#endif
2016-06-15 18:43:10 +12:00
delete (*it);
}
m_pluginTable.clear();
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TPluginManager::loadPlugin(const TFilePath &fp) {
if ((int)m_loadedPlugins.count(fp) > 0) {
TLogger::debug() << "Already loaded " << fp;
return;
}
std::string name = fp.getName();
if (isIgnored(name)) {
TLogger::debug() << "Ignored " << fp;
return;
}
TLogger::debug() << "Loading " << fp;
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-06-15 18:43:10 +12:00
Plugin::Handle handle = LoadLibraryW(fp.getWideString().c_str());
2016-03-19 06:57:51 +13:00
#else
2016-06-15 18:43:10 +12:00
Plugin::Handle handle =
dlopen(::to_string(fp).c_str(), RTLD_NOW); // RTLD_LAZY
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
if (!handle) {
// non riesce a caricare la libreria;
TLogger::warning() << "Unable to load " << fp;
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-06-15 18:43:10 +12:00
std::wstring getFormattedMessage(DWORD lastError);
TLogger::warning() << ::to_string(getFormattedMessage(GetLastError()));
2016-03-19 06:57:51 +13:00
#else
2016-06-15 18:43:10 +12:00
TLogger::warning() << dlerror();
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
} else {
m_loadedPlugins.insert(fp);
Plugin *plugin = new Plugin(handle);
m_pluginTable.push_back(plugin);
// cout << "loaded" << endl;
TnzLibMainProcType *tnzLibMain = 0;
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-06-15 18:43:10 +12:00
tnzLibMain =
(TnzLibMainProcType *)GetProcAddress(handle, TnzLibMainProcName);
2016-03-19 06:57:51 +13:00
#else
2016-06-15 18:43:10 +12:00
tnzLibMain = (TnzLibMainProcType *)dlsym(handle, TnzLibMainProcName);
if (!tnzLibMain) // provo _ come prefisso
tnzLibMain = (TnzLibMainProcType *)dlsym(handle, TnzLibMainProcName2);
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
if (!tnzLibMain) {
// La libreria non esporta TLibMain;
TLogger::warning() << "Corrupted " << fp;
2016-03-19 06:57:51 +13:00
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-06-15 18:43:10 +12:00
FreeLibrary(handle);
2016-03-19 06:57:51 +13:00
#else
2016-06-15 18:43:10 +12:00
dlclose(handle);
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
} else {
const TPluginInfo *info = tnzLibMain();
if (info) plugin->setInfo(*info);
}
}
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TPluginManager::loadPlugins(const TFilePath &dir) {
2016-04-15 17:11:23 +12:00
#if defined(_WIN32)
2016-06-15 18:43:10 +12:00
const std::string extension = "dll";
2016-03-19 06:57:51 +13:00
#elif defined(LINUX) || defined(__sgi)
2016-06-15 18:43:10 +12:00
const std::string extension = "so";
2016-03-19 06:57:51 +13:00
#elif defined(MACOSX)
2016-06-15 18:43:10 +12:00
const std::string extension = "dylib";
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
TFilePathSet dirContent = TSystem::readDirectory(dir, false);
if (dirContent.empty()) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
for (TFilePathSet::iterator it = dirContent.begin(); it != dirContent.end();
it++) {
TFilePath fp = *it;
if (fp.getType() != extension) continue;
std::wstring fullpath = fp.getWideString();
2016-03-19 06:57:51 +13:00
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
bool isDebugLibrary =
(fullpath.find(L".d.") == fullpath.size() - (extension.size() + 3));
2016-03-19 06:57:51 +13:00
#ifdef _DEBUG
2016-06-15 18:43:10 +12:00
if (!isDebugLibrary)
2016-03-19 06:57:51 +13:00
#else
2016-06-15 18:43:10 +12:00
if (isDebugLibrary)
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
continue;
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
try {
loadPlugin(fp);
} catch (...) {
TLogger::warning() << "unexpected error loading " << fp;
}
}
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TPluginManager::loadStandardPlugins() {
TFilePath pluginsDir = TSystem::getDllDir() + "plugins";
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// loadPlugins(pluginsDir + "io");
loadPlugins(pluginsDir + "fx");
2016-03-19 06:57:51 +13:00
}
//--------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TPluginManager::setIgnoredList(const std::set<std::string> &names) {
m_ignoreList.clear();
for (std::set<std::string>::const_iterator it = names.begin();
it != names.end(); ++it)
m_ignoreList.insert(toLower(*it));
2016-03-19 06:57:51 +13:00
}