Refactored adding plugin only after loaded #4866

Conflicts:
	src/lib/arch/unix/ArchPluginUnix.cpp
This commit is contained in:
Jerry (Xinyu Hou) 2015-07-16 12:09:55 -07:00
parent a99699df7a
commit 6602ebe435
5 changed files with 60 additions and 39 deletions

View File

@ -70,7 +70,8 @@ public:
*/ */
virtual void* invoke(const char* plugin, virtual void* invoke(const char* plugin,
const char* command, const char* command,
void** args) = 0; void** args,
void* library = NULL) = 0;
//@} //@}

View File

@ -83,21 +83,20 @@ ArchPluginUnix::load()
} }
String filename = synergy::string::removeFileExt(*it); String filename = synergy::string::removeFileExt(*it);
m_pluginTable.insert(std::make_pair(filename, library));
size_t pos = filename.find("lib"); size_t pos = filename.find("lib");
String pluginName = filename.substr(pos + 3); String pluginName = filename.substr(pos + 3);
char* version = (char*)invoke(filename.c_str(), "version", NULL); char* version = (char*)invoke(filename.c_str(), "version", NULL, library);
String expectedVersion(pluginVersion(pluginName.c_str())); String expectedVersion(pluginVersion(pluginName.c_str()));
if (version != NULL && expectedVersion.compare(version) == 0) { if (version != NULL && expectedVersion.compare(version) == 0) {
LOG((CLOG_DEBUG "loaded plugin: %s (%s)", (*it).c_str(), version)); LOG((CLOG_DEBUG "loaded plugin: %s (%s)", (*it).c_str(), version));
m_pluginTable.insert(std::make_pair(filename, library));
} }
else { else {
LOG((CLOG_WARN "plugin version doesn't match")); LOG((CLOG_WARN "plugin version doesn't match"));
LOG((CLOG_DEBUG "expected plugin version: %s actual plugin version: %s", LOG((CLOG_DEBUG "expected plugin version: %s actual plugin version: %s",
expectedVersion.c_str(), version)); expectedVersion.c_str(), version));
LOG((CLOG_WARN "skip plugin: %s", (*it).c_str())); LOG((CLOG_WARN "skip plugin: %s", (*it).c_str()));
m_pluginTable.erase(filename);
dlclose(library); dlclose(library);
} }
} }
@ -166,26 +165,37 @@ void*
ArchPluginUnix::invoke( ArchPluginUnix::invoke(
const char* plugin, const char* plugin,
const char* command, const char* command,
void** args) void** args,
void* library)
{ {
PluginTable::iterator it; void* lib = NULL;
it = m_pluginTable.find(plugin);
if (it != m_pluginTable.end()) { if (library == NULL) {
invokeFunc invokePlugin = (invokeFunc)dlsym(it->second, "invoke"); PluginTable::iterator it;
void* result = NULL; it = m_pluginTable.find(plugin);
if (invokePlugin != NULL) { if (it != m_pluginTable.end()) {
result = invokePlugin(command, args); lib = it->second;
} }
else { else {
LOG((CLOG_DEBUG "no invoke function in %s", it->first.c_str())); LOG((CLOG_DEBUG "invoke command failed, plugin: %s command: %s",
plugin, command));
return NULL;
} }
return result;
} }
else { else {
LOG((CLOG_DEBUG "invoke command failed, plugin: %s command: %s", lib = library;
plugin, command));
return NULL;
} }
invokeFunc invokePlugin = (invokeFunc)dlsym(lib, "invoke");
void* result = NULL;
if (invokePlugin != NULL) {
result = invokePlugin(command, args);
}
else {
LOG((CLOG_DEBUG "no invoke function in %s", plugin));
}
return result;
} }
String String

View File

@ -38,7 +38,8 @@ public:
bool exists(const char* name); bool exists(const char* name);
virtual void* invoke(const char* pluginName, virtual void* invoke(const char* pluginName,
const char* functionName, const char* functionName,
void** args); void** args,
void* library = NULL);
private: private:
String getPluginsDir(); String getPluginsDir();

View File

@ -70,19 +70,18 @@ ArchPluginWindows::load()
void* lib = reinterpret_cast<void*>(library); void* lib = reinterpret_cast<void*>(library);
String pluginName = synergy::string::removeFileExt(*it); String pluginName = synergy::string::removeFileExt(*it);
m_pluginTable.insert(std::make_pair(pluginName, lib)); char* version = (char*)invoke(pluginName.c_str(), "version", NULL, lib);
char* version = (char*)invoke(pluginName.c_str(), "version", NULL);
String expectedVersion(pluginVersion(pluginName.c_str())); String expectedVersion(pluginVersion(pluginName.c_str()));
if (version != NULL && expectedVersion.compare(version) == 0) { if (version != NULL && expectedVersion.compare(version) == 0) {
LOG((CLOG_DEBUG "loaded plugin: %s (%s)", (*it).c_str(), version)); LOG((CLOG_DEBUG "loaded plugin: %s (%s)", (*it).c_str(), version));
m_pluginTable.insert(std::make_pair(pluginName, lib));
} }
else { else {
LOG((CLOG_WARN "plugin version doesn't match")); LOG((CLOG_WARN "plugin version doesn't match"));
LOG((CLOG_DEBUG "expected plugin version: %s actual plugin version: %s", LOG((CLOG_DEBUG "expected plugin version: %s actual plugin version: %s",
expectedVersion.c_str(), version)); expectedVersion.c_str(), version));
LOG((CLOG_WARN "skip plugin: %s", (*it).c_str())); LOG((CLOG_WARN "skip plugin: %s", (*it).c_str()));
m_pluginTable.erase(pluginName);
FreeLibrary(library); FreeLibrary(library);
} }
} }
@ -158,28 +157,37 @@ void*
ArchPluginWindows::invoke( ArchPluginWindows::invoke(
const char* plugin, const char* plugin,
const char* command, const char* command,
void** args) void** args,
void* library)
{ {
PluginTable::iterator it; HINSTANCE lib = NULL;
it = m_pluginTable.find(plugin);
if (it != m_pluginTable.end()) { if (library == NULL) {
HINSTANCE lib = reinterpret_cast<HINSTANCE>(it->second); PluginTable::iterator it;
invokeFunc invokePlugin = (invokeFunc)GetProcAddress(lib, "invoke"); it = m_pluginTable.find(plugin);
void* result = NULL; if (it != m_pluginTable.end()) {
if (invokePlugin != NULL) { lib = reinterpret_cast<HINSTANCE>(it->second);
result = invokePlugin(command, args);
} }
else { else {
LOG((CLOG_DEBUG "no invoke function in %s", it->first.c_str())); LOG((CLOG_DEBUG "invoke command failed, plugin: %s command: %s",
plugin, command));
return NULL;
} }
return result;
} }
else { else {
LOG((CLOG_DEBUG "invoke command failed, plugin: %s command: %s", lib = reinterpret_cast<HINSTANCE>(library);
plugin, command));
return NULL;
} }
invokeFunc invokePlugin = (invokeFunc)GetProcAddress(lib, "invoke");
void* result = NULL;
if (invokePlugin != NULL) {
result = invokePlugin(command, args);
}
else {
LOG((CLOG_DEBUG "no invoke function in %s", plugin));
}
return result;
} }
void void

View File

@ -41,7 +41,8 @@ public:
bool exists(const char* name); bool exists(const char* name);
void* invoke(const char* pluginName, void* invoke(const char* pluginName,
const char* functionName, const char* functionName,
void** args); void** args,
void* library = NULL);
private: private:
void getFilenames(const String& pattern, std::vector<String>& filenames); void getFilenames(const String& pattern, std::vector<String>& filenames);