added plugin unload and cleanup #4313

This commit is contained in:
XinyuHou 2015-01-27 10:42:10 +00:00
parent 10cddb97a8
commit 85813fd49b
16 changed files with 86 additions and 19 deletions

View File

@ -42,6 +42,12 @@ public:
*/ */
virtual void load() = 0; virtual void load() = 0;
//!Unload plugins
/*!
Look through the loaded plugins and unload them.
*/
virtual void unload() = 0;
//! Init the common parts //! Init the common parts
/*! /*!
Initializes common parts like log and arch. Initializes common parts like log and arch.

View File

@ -31,6 +31,7 @@
typedef void (*initFunc)(void*, void*); typedef void (*initFunc)(void*, void*);
typedef int (*initEventFunc)(void (*sendEvent)(const char*, void*)); typedef int (*initEventFunc)(void (*sendEvent)(const char*, void*));
typedef void* (*invokeFunc)(const char*, void*); typedef void* (*invokeFunc)(const char*, void*);
typedef void (*cleanupFunc)();
void* g_eventTarget = NULL; void* g_eventTarget = NULL;
IEventQueue* g_events = NULL; IEventQueue* g_events = NULL;
@ -84,6 +85,18 @@ ArchPluginUnix::load()
} }
} }
void
ArchPluginUnix::unload()
{
PluginTable::iterator it;
for (it = m_pluginTable.begin(); it != m_pluginTable.end(); it++) {
cleanupFunc cleanup = (cleanupFunc)dlsym(it->second, "cleanup");
cleanup();
LOG((CLOG_DEBUG "unloading plugin: %s", it->first.c_str()));
dlclose(it->second);
}
}
void void
ArchPluginUnix::init(void* log, void* arch) ArchPluginUnix::init(void* log, void* arch)
{ {

View File

@ -32,6 +32,7 @@ public:
// IArchPlugin overrides // IArchPlugin overrides
void load(); void load();
void unload();
void init(void* log, void* arch); void init(void* log, void* arch);
void initEvent(void* eventTarget, IEventQueue* events); void initEvent(void* eventTarget, IEventQueue* events);
bool exists(const char* name); bool exists(const char* name);

View File

@ -30,6 +30,7 @@
typedef void (*initFunc)(void*, void*); typedef void (*initFunc)(void*, void*);
typedef int (*initEventFunc)(void (*sendEvent)(const char*, void*)); typedef int (*initEventFunc)(void (*sendEvent)(const char*, void*));
typedef void* (*invokeFunc)(const char*, void**); typedef void* (*invokeFunc)(const char*, void**);
typedef void (*cleanupFunc)();
void* g_eventTarget = NULL; void* g_eventTarget = NULL;
IEventQueue* g_events = NULL; IEventQueue* g_events = NULL;
@ -68,6 +69,20 @@ ArchPluginWindows::load()
} }
} }
void
ArchPluginWindows::unload()
{
PluginTable::iterator it;
HINSTANCE lib;
for (it = m_pluginTable.begin(); it != m_pluginTable.end(); it++) {
lib = reinterpret_cast<HINSTANCE>(it->second);
cleanupFunc cleanup = (cleanupFunc)GetProcAddress(lib, "cleanup");
cleanup();
LOG((CLOG_DEBUG "unloading plugin: %s", it->first.c_str()));
FreeLibrary(lib);
}
}
void void
ArchPluginWindows::init(void* log, void* arch) ArchPluginWindows::init(void* log, void* arch)
{ {

View File

@ -35,6 +35,7 @@ public:
// IArchPlugin overrides // IArchPlugin overrides
void load(); void load();
void unload();
void init(void* log, void* arch); void init(void* log, void* arch);
void initEvent(void* eventTarget, IEventQueue* events); void initEvent(void* eventTarget, IEventQueue* events);
bool exists(const char* name); bool exists(const char* name);

View File

@ -50,6 +50,8 @@ SecureListenSocket::accept()
socket->initSsl(true); socket->initSsl(true);
// TODO: customized certificate path // TODO: customized certificate path
socket->loadCertificates("C:\\Temp\\synergy.pem"); socket->loadCertificates("C:\\Temp\\synergy.pem");
socket->secureAccept();
if (socket != NULL) { if (socket != NULL) {
m_socketMultiplexer->addSocket(this, m_socketMultiplexer->addSocket(this,
new TSocketMultiplexerMethodJob<TCPListenSocket>( new TSocketMultiplexerMethodJob<TCPListenSocket>(

View File

@ -68,6 +68,21 @@ SecureSocket::~SecureSocket()
delete[] m_error; delete[] m_error;
} }
void
SecureSocket::close()
{
if (m_ssl->m_ssl != NULL) {
SSL_free(m_ssl->m_ssl);
m_ssl->m_ssl = NULL;
}
if (m_ssl->m_context != NULL) {
SSL_CTX_free(m_ssl->m_context);
m_ssl->m_context = NULL;
}
TCPSocket::close();
}
void void
SecureSocket::secureConnect() SecureSocket::secureConnect()

View File

@ -42,6 +42,8 @@ public:
ArchSocket socket); ArchSocket socket);
~SecureSocket(); ~SecureSocket();
// ISocket overrides
void close();
void secureConnect(); void secureConnect();
void secureAccept(); void secureAccept();

View File

@ -79,7 +79,7 @@ invoke(const char* command, void** args)
} }
} }
int void
cleanup() cleanup()
{ {
if (g_secureSocket != NULL) { if (g_secureSocket != NULL) {
@ -89,8 +89,6 @@ cleanup()
if (g_secureListenSocket != NULL) { if (g_secureListenSocket != NULL) {
delete g_secureListenSocket; delete g_secureListenSocket;
} }
return 0;
} }
} }

View File

@ -36,6 +36,6 @@ extern "C" {
NS_API void init(void* log, void* arch); NS_API void init(void* log, void* arch);
NS_API int initEvent(void (*sendEvent)(const char*, void*)); NS_API int initEvent(void (*sendEvent)(const char*, void*));
NS_API void* invoke(const char* command, void** args); NS_API void* invoke(const char* command, void** args);
NS_API int cleanup(); NS_API void cleanup();
} }

View File

@ -49,12 +49,10 @@ initEvent(void (*sendEvent)(const char*, void*))
return 0; return 0;
} }
int void
cleanup() cleanup()
{ {
LOG("cleanup");
s_running = false; s_running = false;
return 0;
} }
} }

View File

@ -31,7 +31,7 @@ extern "C" {
WINMMJOY_API void init(void* log, void* arch); WINMMJOY_API void init(void* log, void* arch);
WINMMJOY_API int initEvent(void (*sendEvent)(const char*, void*)); WINMMJOY_API int initEvent(void (*sendEvent)(const char*, void*));
WINMMJOY_API int cleanup(); WINMMJOY_API void cleanup();
} }

View File

@ -21,7 +21,6 @@
#include "server/ClientProxy.h" #include "server/ClientProxy.h"
#include "server/ClientProxyUnknown.h" #include "server/ClientProxyUnknown.h"
#include "synergy/PacketStreamFilter.h" #include "synergy/PacketStreamFilter.h"
#include "net/TCPSocket.h"
#include "net/IDataSocket.h" #include "net/IDataSocket.h"
#include "net/IListenSocket.h" #include "net/IListenSocket.h"
#include "net/ISocketFactory.h" #include "net/ISocketFactory.h"
@ -58,21 +57,21 @@ ClientListener::ClientListener(const NetworkAddress& address,
try { try {
// create listen socket // create listen socket
bool useSecureSocket = ARCH->plugin().exists(s_networkSecurity); m_useSecureSocket = ARCH->plugin().exists(s_networkSecurity);
m_listen = m_socketFactory->createListen(useSecureSocket); m_listen = m_socketFactory->createListen(m_useSecureSocket);
// bind listen address // bind listen address
LOG((CLOG_DEBUG1 "binding listen socket")); LOG((CLOG_DEBUG1 "binding listen socket"));
m_listen->bind(address); m_listen->bind(address);
} }
catch (XSocketAddressInUse&) { catch (XSocketAddressInUse&) {
delete m_listen; cleanupListenSocket();
delete m_socketFactory; delete m_socketFactory;
delete m_streamFilterFactory; delete m_streamFilterFactory;
throw; throw;
} }
catch (XBase&) { catch (XBase&) {
delete m_listen; cleanupListenSocket();
delete m_socketFactory; delete m_socketFactory;
delete m_streamFilterFactory; delete m_streamFilterFactory;
throw; throw;
@ -110,7 +109,7 @@ ClientListener::~ClientListener()
} }
m_events->removeHandler(m_events->forIListenSocket().connecting(), m_listen); m_events->removeHandler(m_events->forIListenSocket().connecting(), m_listen);
delete m_listen; cleanupListenSocket();
delete m_socketFactory; delete m_socketFactory;
delete m_streamFilterFactory; delete m_streamFilterFactory;
} }
@ -143,8 +142,7 @@ ClientListener::handleClientConnecting(const Event&, void*)
return; return;
} }
LOG((CLOG_NOTE "accepted client connection")); LOG((CLOG_NOTE "accepted client connection"));
TCPSocket* socket = dynamic_cast<TCPSocket*>(stream);
socket->secureAccept();
// filter socket messages, including a packetizing filter // filter socket messages, including a packetizing filter
if (m_streamFilterFactory != NULL) { if (m_streamFilterFactory != NULL) {
stream = m_streamFilterFactory->create(stream, true); stream = m_streamFilterFactory->create(stream, true);
@ -219,3 +217,11 @@ ClientListener::handleClientDisconnected(const Event&, void* vclient)
} }
} }
} }
void
ClientListener::cleanupListenSocket()
{
if (!m_useSecureSocket) {
delete m_listen;
}
}

View File

@ -73,16 +73,20 @@ private:
void handleUnknownClient(const Event&, void*); void handleUnknownClient(const Event&, void*);
void handleClientDisconnected(const Event&, void*); void handleClientDisconnected(const Event&, void*);
void cleanupListenSocket();
private: private:
typedef std::set<ClientProxyUnknown*> NewClients; typedef std::set<ClientProxyUnknown*> NewClients;
typedef std::deque<ClientProxy*> WaitingClients; typedef std::deque<ClientProxy*> WaitingClients;
IListenSocket* m_listen; IListenSocket* m_listen;
ISocketFactory* m_socketFactory; ISocketFactory* m_socketFactory;
IStreamFilterFactory* m_streamFilterFactory; IStreamFilterFactory*
m_streamFilterFactory;
NewClients m_newClients; NewClients m_newClients;
WaitingClients m_waitingClients; WaitingClients m_waitingClients;
Server* m_server; Server* m_server;
CryptoOptions m_crypto; CryptoOptions m_crypto;
IEventQueue* m_events; IEventQueue* m_events;
bool m_useSecureSocket;
}; };

View File

@ -509,6 +509,9 @@ ClientApp::mainLoop()
cleanupIpcClient(); cleanupIpcClient();
} }
// unload all plugins.
ARCH->plugin().unload();
return kExitSuccess; return kExitSuccess;
} }

View File

@ -780,6 +780,9 @@ ServerApp::mainLoop()
cleanupIpcClient(); cleanupIpcClient();
} }
// unload all plugins.
ARCH->plugin().unload();
return kExitSuccess; return kExitSuccess;
} }