From 3d6551f70897206e976ff89d76abccd8e1a7f222 Mon Sep 17 00:00:00 2001 From: Nick Bolton Date: Thu, 5 Jul 2012 18:05:35 +0000 Subject: [PATCH] moved stream into synergy namespace (to prevent naming collision in win libs) implemented ipc "hello" message (to identify client type) integ tests working for hello message, but use of ipc in main program has problem with events. --- src/cmd/synergyc/CMakeLists.txt | 3 +- src/cmd/synergys/CMakeLists.txt | 3 +- src/gui/src/IpcClient.cpp | 11 ++++++ src/gui/src/IpcClient.h | 13 ++++++- src/gui/src/MainWindow.cpp | 5 +++ src/lib/client/CClient.h | 4 +- src/lib/client/CServerProxy.cpp | 2 +- src/lib/client/CServerProxy.h | 6 +-- src/lib/io/CStreamFilter.cpp | 4 +- src/lib/io/CStreamFilter.h | 8 ++-- src/lib/io/IStream.cpp | 2 + src/lib/io/IStream.h | 4 ++ src/lib/io/IStreamFilterFactory.h | 5 ++- src/lib/ipc/CIpcClient.cpp | 28 ++++++++++++++ src/lib/ipc/CIpcClient.h | 23 ++++++++++-- src/lib/ipc/CIpcClientProxy.cpp | 46 ++++++++++++++++------- src/lib/ipc/CIpcClientProxy.h | 13 ++++--- src/lib/ipc/CIpcLogOutputter.cpp | 2 +- src/lib/ipc/CIpcServer.cpp | 21 +++++++---- src/lib/ipc/CIpcServer.h | 7 ++-- src/lib/ipc/CIpcServerProxy.cpp | 38 ++++++++++++------- src/lib/ipc/CIpcServerProxy.h | 6 +-- src/lib/ipc/Ipc.h | 10 ++++- src/lib/net/IDataSocket.h | 2 +- src/lib/platform/CMSWindowsRelauncher.cpp | 27 +++++++++---- src/lib/platform/CMSWindowsRelauncher.h | 11 ++++-- src/lib/platform/CMakeLists.txt | 4 +- src/lib/server/CClientListener.cpp | 6 +-- src/lib/server/CClientProxy.cpp | 4 +- src/lib/server/CClientProxy.h | 8 ++-- src/lib/server/CClientProxy1_0.cpp | 2 +- src/lib/server/CClientProxy1_0.h | 2 +- src/lib/server/CClientProxy1_1.cpp | 2 +- src/lib/server/CClientProxy1_1.h | 2 +- src/lib/server/CClientProxy1_2.cpp | 2 +- src/lib/server/CClientProxy1_2.h | 2 +- src/lib/server/CClientProxy1_3.cpp | 2 +- src/lib/server/CClientProxy1_3.h | 2 +- src/lib/server/CClientProxy1_4.cpp | 2 +- src/lib/server/CClientProxy1_4.h | 2 +- src/lib/server/CClientProxyUnknown.cpp | 2 +- src/lib/server/CClientProxyUnknown.h | 6 +-- src/lib/synergy/CApp.cpp | 41 +++++++++++++++++++- src/lib/synergy/CApp.h | 7 ++++ src/lib/synergy/CAppUtilWindows.cpp | 15 +------- src/lib/synergy/CArgsBase.cpp | 1 - src/lib/synergy/CArgsBase.h | 2 +- src/lib/synergy/CClientApp.cpp | 4 ++ src/lib/synergy/CDaemonApp.cpp | 29 +++++++------- src/lib/synergy/CDaemonApp.h | 7 +--- src/lib/synergy/CPacketStreamFilter.cpp | 2 +- src/lib/synergy/CPacketStreamFilter.h | 2 +- src/lib/synergy/CProtocolUtil.cpp | 10 ++--- src/lib/synergy/CProtocolUtil.h | 12 +++--- src/lib/synergy/CServerApp.cpp | 9 +++++ src/test/integtests/CIpcTests.cpp | 43 +++++++++++---------- src/test/unittests/io/CMockStream.h | 2 +- 57 files changed, 367 insertions(+), 173 deletions(-) diff --git a/src/cmd/synergyc/CMakeLists.txt b/src/cmd/synergyc/CMakeLists.txt index 9512b9f5c..357580b24 100644 --- a/src/cmd/synergyc/CMakeLists.txt +++ b/src/cmd/synergyc/CMakeLists.txt @@ -41,6 +41,7 @@ set(inc ../../lib/client ../../lib/common ../../lib/io + ../../lib/ipc ../../lib/mt ../../lib/net ../../lib/platform @@ -60,7 +61,7 @@ endif() include_directories(${inc}) add_executable(synergyc ${src}) target_link_libraries(synergyc - arch base client common io mt net platform server synergy ${libs}) + arch base client common io mt net ipc platform server synergy ${libs}) if (CONF_CPACK) install(TARGETS diff --git a/src/cmd/synergys/CMakeLists.txt b/src/cmd/synergys/CMakeLists.txt index a389c4975..3a6dcb97b 100644 --- a/src/cmd/synergys/CMakeLists.txt +++ b/src/cmd/synergys/CMakeLists.txt @@ -40,6 +40,7 @@ set(inc ../../lib/base ../../lib/common ../../lib/io + ../../lib/ipc ../../lib/mt ../../lib/net ../../lib/platform @@ -60,7 +61,7 @@ endif() include_directories(${inc}) add_executable(synergys ${src}) target_link_libraries(synergys - arch base client common io mt net platform server synergy ${libs}) + arch base client common io mt net ipc platform server synergy ${libs}) if (CONF_CPACK) install(TARGETS diff --git a/src/gui/src/IpcClient.cpp b/src/gui/src/IpcClient.cpp index 2dacad025..a8cba8151 100644 --- a/src/gui/src/IpcClient.cpp +++ b/src/gui/src/IpcClient.cpp @@ -25,6 +25,7 @@ IpcClient::IpcClient() { m_Socket = new QTcpSocket(this); connect(m_Socket, SIGNAL(readyRead()), this, SLOT(read())); + connect(m_Socket, SIGNAL(connected()), this, SLOT(connected())); connect(m_Socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); } @@ -32,6 +33,15 @@ IpcClient::~IpcClient() { } +void IpcClient::connected() +{ + infoMessage("connected to background service"); + + char typeBuf[1]; + typeBuf[0] = kIpcClientGui; + write(kIpcHello, 1, typeBuf); +} + void IpcClient::connectToHost() { infoMessage("connecting to background service..."); @@ -52,6 +62,7 @@ void IpcClient::read() char lenBuf[2]; stream.readRawData(lenBuf, 2); int len = bytesToInt(lenBuf, 2); + std::cout << "len: " << len << std::endl; char* data = new char[len]; stream.readRawData(data, len); diff --git a/src/gui/src/IpcClient.h b/src/gui/src/IpcClient.h index 0be5a6957..19fd97784 100644 --- a/src/gui/src/IpcClient.h +++ b/src/gui/src/IpcClient.h @@ -42,6 +42,7 @@ private: void intToBytes(int value, char* buffer, int size); private slots: + void connected(); void read(); void error(QAbstractSocket::SocketError error); @@ -54,7 +55,15 @@ private: QTcpSocket* m_Socket; }; -enum EIpcMessage { +enum IpcMessageType { + kIpcHello, kIpcLogLine, - kIpcCommand + kIpcCommand, + kIpcShutdown, +}; + +enum IpcClientType { + kIpcClientUnknown, + kIpcClientGui, + kIpcClientNode, }; diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 2170261c6..ffb3d4431 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -369,6 +369,11 @@ void MainWindow::startSynergy() { setSynergyProcess(new QProcess(this)); } + else + { + // tell client/server to talk to daemon through ipc. + args << "--ipc"; + } if ((synergyType() == synergyClient && !clientArgs(args, app)) || (synergyType() == synergyServer && !serverArgs(args, app))) diff --git a/src/lib/client/CClient.h b/src/lib/client/CClient.h index 0216d5588..69fd4962d 100644 --- a/src/lib/client/CClient.h +++ b/src/lib/client/CClient.h @@ -28,7 +28,7 @@ class CScreen; class CServerProxy; class IDataSocket; class ISocketFactory; -class IStream; +namespace synergy { class IStream; } class IStreamFilterFactory; class IEventQueue; @@ -195,7 +195,7 @@ private: ISocketFactory* m_socketFactory; IStreamFilterFactory* m_streamFilterFactory; CScreen* m_screen; - IStream* m_stream; + synergy::IStream* m_stream; CEventQueueTimer* m_timer; CServerProxy* m_server; bool m_ready; diff --git a/src/lib/client/CServerProxy.cpp b/src/lib/client/CServerProxy.cpp index 22cb0785a..d34c594bf 100644 --- a/src/lib/client/CServerProxy.cpp +++ b/src/lib/client/CServerProxy.cpp @@ -33,7 +33,7 @@ // CServerProxy // -CServerProxy::CServerProxy(CClient* client, IStream* stream, IEventQueue& eventQueue) : +CServerProxy::CServerProxy(CClient* client, synergy::IStream* stream, IEventQueue& eventQueue) : m_client(client), m_stream(stream), m_seqNum(0), diff --git a/src/lib/client/CServerProxy.h b/src/lib/client/CServerProxy.h index 6a4b65906..20e5328c1 100644 --- a/src/lib/client/CServerProxy.h +++ b/src/lib/client/CServerProxy.h @@ -27,7 +27,7 @@ class CClient; class CClientInfo; class CEventQueueTimer; class IClipboard; -class IStream; +namespace synergy { class IStream; } class IEventQueue; //! Proxy for server @@ -41,7 +41,7 @@ public: Process messages from the server on \p stream and forward to \p client. */ - CServerProxy(CClient* client, IStream* stream, IEventQueue& eventQueue); + CServerProxy(CClient* client, synergy::IStream* stream, IEventQueue& eventQueue); ~CServerProxy(); //! @name manipulators @@ -104,7 +104,7 @@ private: typedef EResult (CServerProxy::*MessageParser)(const UInt8*); CClient* m_client; - IStream* m_stream; + synergy::IStream* m_stream; UInt32 m_seqNum; diff --git a/src/lib/io/CStreamFilter.cpp b/src/lib/io/CStreamFilter.cpp index 830b427aa..85695f3ba 100644 --- a/src/lib/io/CStreamFilter.cpp +++ b/src/lib/io/CStreamFilter.cpp @@ -23,7 +23,7 @@ // CStreamFilter // -CStreamFilter::CStreamFilter(IStream* stream, bool adoptStream) : +CStreamFilter::CStreamFilter(synergy::IStream* stream, bool adoptStream) : m_stream(stream), m_adopted(adoptStream) { @@ -96,7 +96,7 @@ CStreamFilter::getSize() const return getStream()->getSize(); } -IStream* +synergy::IStream* CStreamFilter::getStream() const { return m_stream; diff --git a/src/lib/io/CStreamFilter.h b/src/lib/io/CStreamFilter.h index bcab9f6a2..f5aa6e224 100644 --- a/src/lib/io/CStreamFilter.h +++ b/src/lib/io/CStreamFilter.h @@ -25,14 +25,14 @@ This class wraps a stream. Subclasses provide indirect access to the wrapped stream, typically performing some filtering. */ -class CStreamFilter : public IStream { +class CStreamFilter : public synergy::IStream { public: /*! Create a wrapper around \c stream. Iff \c adoptStream is true then this object takes ownership of the stream and will delete it in the d'tor. */ - CStreamFilter(IStream* stream, bool adoptStream = true); + CStreamFilter(synergy::IStream* stream, bool adoptStream = true); ~CStreamFilter(); // IStream overrides @@ -53,7 +53,7 @@ protected: /*! Returns the stream passed to the c'tor. */ - IStream* getStream() const; + synergy::IStream* getStream() const; //! Handle events from source stream /*! @@ -66,7 +66,7 @@ private: void handleUpstreamEvent(const CEvent&, void*); private: - IStream* m_stream; + synergy::IStream* m_stream; bool m_adopted; }; diff --git a/src/lib/io/IStream.cpp b/src/lib/io/IStream.cpp index f8e813ef2..4a6db2a17 100644 --- a/src/lib/io/IStream.cpp +++ b/src/lib/io/IStream.cpp @@ -18,6 +18,8 @@ #include "IStream.h" #include "CEventQueue.h" +using namespace synergy; + // // IStream // diff --git a/src/lib/io/IStream.h b/src/lib/io/IStream.h index 6c33ca63a..eba56051f 100644 --- a/src/lib/io/IStream.h +++ b/src/lib/io/IStream.h @@ -24,6 +24,8 @@ class IEventQueue; +namespace synergy { + //! Bidirectional stream interface /*! Defines the interface for all streams. @@ -165,4 +167,6 @@ private: static CEvent::Type s_outputShutdownEvent; }; +} + #endif diff --git a/src/lib/io/IStreamFilterFactory.h b/src/lib/io/IStreamFilterFactory.h index 449df64f7..77750747a 100644 --- a/src/lib/io/IStreamFilterFactory.h +++ b/src/lib/io/IStreamFilterFactory.h @@ -20,7 +20,8 @@ #include "IInterface.h" -class IStream; +using namespace synergy; +namespace synergy { class IStream; } //! Stream filter factory interface /*! @@ -33,7 +34,7 @@ public: Create and return a stream filter on \p stream. The caller must delete the returned object. */ - virtual IStream* create(IStream* stream, bool adoptStream) = 0; + virtual synergy::IStream* create(IStream* stream, bool adoptStream) = 0; }; #endif diff --git a/src/lib/ipc/CIpcClient.cpp b/src/lib/ipc/CIpcClient.cpp index 61c323899..50515afb5 100644 --- a/src/lib/ipc/CIpcClient.cpp +++ b/src/lib/ipc/CIpcClient.cpp @@ -18,16 +18,26 @@ #include "CIpcClient.h" #include "Ipc.h" #include "CIpcServerProxy.h" +#include "TMethodEventJob.h" +#include "CIpcMessage.h" + +CEvent::Type CIpcClient::s_connectedEvent = CEvent::kUnknown; CIpcClient::CIpcClient() : m_serverAddress(CNetworkAddress(IPC_HOST, IPC_PORT)), m_server(nullptr) { m_serverAddress.resolve(); + + EVENTQUEUE->adoptHandler( + m_socket.getConnectedEvent(), &m_socket, + new TMethodEventJob( + this, &CIpcClient::handleConnected)); } CIpcClient::~CIpcClient() { + delete m_server; } void @@ -43,3 +53,21 @@ CIpcClient::send(const CIpcMessage& message) assert(m_server != NULL); m_server->send(message); } + +CEvent::Type +CIpcClient::getConnectedEvent() +{ + return EVENTQUEUE->registerTypeOnce( + s_connectedEvent, "CIpcClient::connected"); +} + +void +CIpcClient::handleConnected(const CEvent&, void*) +{ + EVENTQUEUE->addEvent(CEvent(getConnectedEvent(), this, m_server, CEvent::kDontFreeData)); + + CIpcMessage message; + message.m_type = kIpcHello; + message.m_data = new UInt8(kIpcClientNode); + send(message); +} diff --git a/src/lib/ipc/CIpcClient.h b/src/lib/ipc/CIpcClient.h index 7b365eb2e..91e94a8eb 100644 --- a/src/lib/ipc/CIpcClient.h +++ b/src/lib/ipc/CIpcClient.h @@ -32,14 +32,31 @@ public: CIpcClient(); virtual ~CIpcClient(); + //! @name manipulators + //@{ + //! Connects to the IPC server at localhost. void connect(); //! Sends a message to the server. void send(const CIpcMessage& message); + //@} + //! @name accessors + //@{ + + //! Raised when the socket is connected. + static CEvent::Type getConnectedEvent(); + + //@} + private: - CNetworkAddress m_serverAddress; - CTCPSocket m_socket; - CIpcServerProxy* m_server; + void handleConnected(const CEvent&, void*); + +private: + CNetworkAddress m_serverAddress; + CTCPSocket m_socket; + CIpcServerProxy* m_server; + + static CEvent::Type s_connectedEvent; }; diff --git a/src/lib/ipc/CIpcClientProxy.cpp b/src/lib/ipc/CIpcClientProxy.cpp index 4f3fb5428..42e1e780b 100644 --- a/src/lib/ipc/CIpcClientProxy.cpp +++ b/src/lib/ipc/CIpcClientProxy.cpp @@ -25,20 +25,23 @@ CEvent::Type CIpcClientProxy::s_messageReceivedEvent = CEvent::kUnknown; -CIpcClientProxy::CIpcClientProxy(IStream& stream) : +CIpcClientProxy::CIpcClientProxy(synergy::IStream& stream) : m_stream(stream), -m_enableLog(false) +m_enableLog(false), +m_clientType(kIpcClientUnknown) { - EVENTQUEUE->adoptHandler(m_stream.getInputReadyEvent(), - stream.getEventTarget(), + EVENTQUEUE->adoptHandler( + m_stream.getInputReadyEvent(), stream.getEventTarget(), new TMethodEventJob( this, &CIpcClientProxy::handleData, nullptr)); } CIpcClientProxy::~CIpcClientProxy() { - EVENTQUEUE->removeHandler(m_stream.getInputReadyEvent(), - m_stream.getEventTarget()); + EVENTQUEUE->removeHandler( + m_stream.getInputReadyEvent(), m_stream.getEventTarget()); + + m_stream.close(); } void @@ -57,6 +60,10 @@ CIpcClientProxy::handleData(const CEvent&, void*) } switch (type) { + case kIpcHello: + parseHello(); + break; + case kIpcCommand: m->m_data = parseCommand(); break; @@ -87,14 +94,18 @@ CIpcClientProxy::send(const CIpcMessage& message) switch (message.m_type) { case kIpcLogLine: { - CString* s = (CString*)message.m_data; - const char* data = s->c_str(); - - int len = strlen(data); - CProtocolUtil::writef(&m_stream, "%2i", len); + CString* s = (CString*)message.m_data; + const char* data = s->c_str(); + + int len = strlen(data); + CProtocolUtil::writef(&m_stream, "%2i", len); - m_stream.write(data, len); - } + m_stream.write(data, len); + break; + } + + case kIpcShutdown: + // no data. break; default: @@ -105,6 +116,14 @@ CIpcClientProxy::send(const CIpcMessage& message) } } +void +CIpcClientProxy::parseHello() +{ + UInt8 buffer[1]; + m_stream.read(buffer, 1); + m_clientType = static_cast(buffer[0]); +} + void* CIpcClientProxy::parseCommand() { @@ -114,6 +133,7 @@ CIpcClientProxy::parseCommand() UInt8* buffer = new UInt8[len]; m_stream.read(buffer, len); + // delete by event cleanup. return new CString((const char*)buffer, len); } diff --git a/src/lib/ipc/CIpcClientProxy.h b/src/lib/ipc/CIpcClientProxy.h index 381c38491..5e76e4bbd 100644 --- a/src/lib/ipc/CIpcClientProxy.h +++ b/src/lib/ipc/CIpcClientProxy.h @@ -18,29 +18,32 @@ #pragma once #include "CEvent.h" +#include "Ipc.h" -class IStream; +namespace synergy { class IStream; } class CIpcMessage; class CIpcClientProxy { public: - CIpcClientProxy(IStream& stream); + CIpcClientProxy(synergy::IStream& stream); virtual ~CIpcClientProxy(); //! Send a message to the client. - void send(const CIpcMessage& message); + void send(const CIpcMessage& message); //! Raised when the server receives a message from a client. - static CEvent::Type getMessageReceivedEvent(); + static CEvent::Type getMessageReceivedEvent(); private: void handleData(const CEvent&, void*); + void parseHello(); void* parseCommand(); void disconnect(); public: - IStream& m_stream; + synergy::IStream& m_stream; bool m_enableLog; + EIpcClientType m_clientType; private: static CEvent::Type s_messageReceivedEvent; diff --git a/src/lib/ipc/CIpcLogOutputter.cpp b/src/lib/ipc/CIpcLogOutputter.cpp index 0a42af6a0..fd665c13d 100644 --- a/src/lib/ipc/CIpcLogOutputter.cpp +++ b/src/lib/ipc/CIpcLogOutputter.cpp @@ -50,6 +50,6 @@ CIpcLogOutputter::write(ELevel level, const char* msg) CIpcMessage message; message.m_type = kIpcLogLine; message.m_data = new CString(msg); - m_ipcServer.send(message); + m_ipcServer.send(message, kIpcClientGui); return true; } diff --git a/src/lib/ipc/CIpcServer.cpp b/src/lib/ipc/CIpcServer.cpp index 4fc66d223..ada173fcf 100644 --- a/src/lib/ipc/CIpcServer.cpp +++ b/src/lib/ipc/CIpcServer.cpp @@ -34,14 +34,19 @@ m_address(CNetworkAddress(IPC_HOST, IPC_PORT)) m_address.resolve(); EVENTQUEUE->adoptHandler( - IListenSocket::getConnectingEvent(), &m_socket, + m_socket.getConnectingEvent(), &m_socket, new TMethodEventJob( this, &CIpcServer::handleClientConnecting)); } CIpcServer::~CIpcServer() { - EVENTQUEUE->removeHandler(IListenSocket::getConnectingEvent(), &m_socket); + CClientSet::iterator it; + for (it = m_clients.begin(); it != m_clients.end(); it++) { + delete *it; + } + + EVENTQUEUE->removeHandler(m_socket.getConnectingEvent(), &m_socket); } void @@ -53,12 +58,11 @@ CIpcServer::listen() void CIpcServer::handleClientConnecting(const CEvent&, void*) { - IStream* stream = m_socket.accept(); + synergy::IStream* stream = m_socket.accept(); if (stream == NULL) { return; } - // when there is already a client connected, this causes stack overflow, - // + LOG((CLOG_NOTE "accepted ipc client connection")); // TODO: delete on disconnect @@ -76,10 +80,13 @@ CIpcServer::getClientConnectedEvent() } void -CIpcServer::send(const CIpcMessage& message) +CIpcServer::send(const CIpcMessage& message, EIpcClientType filterType) { CClientSet::iterator it; for (it = m_clients.begin(); it != m_clients.end(); it++) { - (*it)->send(message); + CIpcClientProxy* proxy = *it; + if (proxy->m_clientType == filterType) { + proxy->send(message); + } } } diff --git a/src/lib/ipc/CIpcServer.h b/src/lib/ipc/CIpcServer.h index d0ccffbf5..19a49cfad 100644 --- a/src/lib/ipc/CIpcServer.h +++ b/src/lib/ipc/CIpcServer.h @@ -19,6 +19,7 @@ #include "CTCPListenSocket.h" #include "CNetworkAddress.h" +#include "Ipc.h" #include class CEvent; @@ -43,15 +44,15 @@ public: //! Opens a TCP socket only allowing local connections. void listen(); - //! Send a message to all clients. - void send(const CIpcMessage& message); + //! Send a message to all clients matching the filter type. + void send(const CIpcMessage& message, EIpcClientType filterType); //@} //! @name accessors //@{ //! Raised when we have created the client proxy. - static CEvent::Type getClientConnectedEvent(); + static CEvent::Type getClientConnectedEvent(); //@} diff --git a/src/lib/ipc/CIpcServerProxy.cpp b/src/lib/ipc/CIpcServerProxy.cpp index 70aef8d7b..f073be695 100644 --- a/src/lib/ipc/CIpcServerProxy.cpp +++ b/src/lib/ipc/CIpcServerProxy.cpp @@ -25,19 +25,21 @@ CEvent::Type CIpcServerProxy::s_messageReceivedEvent = CEvent::kUnknown; -CIpcServerProxy::CIpcServerProxy(IStream& stream) : +CIpcServerProxy::CIpcServerProxy(synergy::IStream& stream) : m_stream(stream) { EVENTQUEUE->adoptHandler(m_stream.getInputReadyEvent(), stream.getEventTarget(), new TMethodEventJob( - this, &CIpcServerProxy::handleData, nullptr)); + this, &CIpcServerProxy::handleData)); } CIpcServerProxy::~CIpcServerProxy() { EVENTQUEUE->removeHandler(m_stream.getInputReadyEvent(), m_stream.getEventTarget()); + + m_stream.close(); } void @@ -48,13 +50,17 @@ CIpcServerProxy::handleData(const CEvent&, void*) while (n != 0) { CIpcMessage* m = new CIpcMessage(); - m->m_type = code[1]; + m->m_type = code[0]; - LOG((CLOG_DEBUG "ipc server proxy read: %d", code[0])); - switch (code[0]) { + LOG((CLOG_DEBUG "ipc server proxy read: %d", m->m_type)); + switch (m->m_type) { case kIpcLogLine: m->m_data = parseLogLine(); break; + + case kIpcShutdown: + // no data. + break; default: delete m; @@ -79,17 +85,21 @@ CIpcServerProxy::send(const CIpcMessage& message) m_stream.write(code, 1); switch (message.m_type) { - case kIpcCommand: { - CString* s = (CString*)message.m_data; - const char* data = s->c_str(); - - int len = strlen(data); - CProtocolUtil::writef(&m_stream, "%2i", len); - - m_stream.write(data, len); - } + case kIpcHello: + m_stream.write(message.m_data, 1); break; + case kIpcCommand: { + CString* s = (CString*)message.m_data; + const char* data = s->c_str(); + + int len = strlen(data); + CProtocolUtil::writef(&m_stream, "%2i", len); + + m_stream.write(data, len); + break; + } + default: LOG((CLOG_ERR "message not supported: %d", message.m_type)); break; diff --git a/src/lib/ipc/CIpcServerProxy.h b/src/lib/ipc/CIpcServerProxy.h index 428957544..a5e3147bb 100644 --- a/src/lib/ipc/CIpcServerProxy.h +++ b/src/lib/ipc/CIpcServerProxy.h @@ -19,12 +19,12 @@ #include "CEvent.h" -class IStream; +namespace synergy { class IStream; } class CIpcMessage; class CIpcServerProxy { public: - CIpcServerProxy(IStream& stream); + CIpcServerProxy(synergy::IStream& stream); virtual ~CIpcServerProxy(); void send(const CIpcMessage& message); @@ -38,7 +38,7 @@ private: void disconnect(); private: - IStream& m_stream; + synergy::IStream& m_stream; static CEvent::Type s_messageReceivedEvent; }; diff --git a/src/lib/ipc/Ipc.h b/src/lib/ipc/Ipc.h index 66837fd38..af388fd58 100644 --- a/src/lib/ipc/Ipc.h +++ b/src/lib/ipc/Ipc.h @@ -21,6 +21,14 @@ #define IPC_PORT 24801 enum EIpcMessage { + kIpcHello, kIpcLogLine, - kIpcCommand + kIpcCommand, + kIpcShutdown, +}; + +enum EIpcClientType { + kIpcClientUnknown, + kIpcClientGui, + kIpcClientNode, }; diff --git a/src/lib/net/IDataSocket.h b/src/lib/net/IDataSocket.h index 7a27a63ba..1aa5c897a 100644 --- a/src/lib/net/IDataSocket.h +++ b/src/lib/net/IDataSocket.h @@ -27,7 +27,7 @@ This interface defines the methods common to all network sockets that represent a full-duplex data stream. */ -class IDataSocket : public ISocket, public IStream { +class IDataSocket : public ISocket, public synergy::IStream { public: class CConnectionFailedInfo { public: diff --git a/src/lib/platform/CMSWindowsRelauncher.cpp b/src/lib/platform/CMSWindowsRelauncher.cpp index 4c878f323..34fcb2506 100644 --- a/src/lib/platform/CMSWindowsRelauncher.cpp +++ b/src/lib/platform/CMSWindowsRelauncher.cpp @@ -26,6 +26,9 @@ #include "CApp.h" #include "CArgsBase.h" #include "CIpcLogOutputter.h" +#include "CIpcServer.h" +#include "CIpcMessage.h" +#include "Ipc.h" #include #include @@ -37,14 +40,18 @@ enum { typedef VOID (WINAPI *SendSas)(BOOL asUser); -CMSWindowsRelauncher::CMSWindowsRelauncher(bool autoDetectCommand) : +CMSWindowsRelauncher::CMSWindowsRelauncher( + bool autoDetectCommand, + CIpcServer& ipcServer, + CIpcLogOutputter& ipcLogOutputter) : m_thread(NULL), m_autoDetectCommand(autoDetectCommand), m_running(true), m_commandChanged(false), m_stdOutWrite(NULL), m_stdOutRead(NULL), - m_ipcLogOutputter(nullptr) + m_ipcServer(ipcServer), + m_ipcLogOutputter(ipcLogOutputter) { } @@ -374,7 +381,7 @@ CMSWindowsRelauncher::command() const // build up a full command line std::stringstream cmdTemp; - cmdTemp << launchName << /*" --debug-data session-" << sessionId <<*/ args; + cmdTemp << launchName << args; std::string cmd = cmdTemp.str(); @@ -390,7 +397,8 @@ CMSWindowsRelauncher::command() const void CMSWindowsRelauncher::outputLoop(void*) { - CHAR buffer[kOutputBufferSize]; + // +1 char for \0 + CHAR buffer[kOutputBufferSize + 1]; while (true) { @@ -405,7 +413,7 @@ CMSWindowsRelauncher::outputLoop(void*) else { // send process output over IPC to GUI. buffer[bytesRead] = '\0'; - m_ipcLogOutputter->write(kINFO, buffer); + m_ipcLogOutputter.write(kINFO, buffer); } } @@ -419,6 +427,10 @@ CMSWindowsRelauncher::shutdownProcess(const PROCESS_INFORMATION& pi, int timeout if (exitCode != STILL_ACTIVE) return; + CIpcMessage shutdown; + shutdown.m_type = kIpcShutdown; + m_ipcServer.send(shutdown, kIpcClientNode); + // wait for process to exit gracefully. double start = ARCH->time(); while (true) @@ -430,12 +442,13 @@ CMSWindowsRelauncher::shutdownProcess(const PROCESS_INFORMATION& pi, int timeout } else { - if ((ARCH->time() - start) > timeout) { + double elapsed = (ARCH->time() - start); + if (elapsed > timeout) { // if timeout reached, kill forcefully. // calling TerminateProcess on synergy is very bad! // it causes the hook DLL to stay loaded in some apps, // making it impossible to start synergy again. - LOG((CLOG_WARN "shutdown timed out after %d secs, forcefully terminating", pi.dwProcessId)); + LOG((CLOG_WARN "shutdown timed out after %d secs, forcefully terminating", (int)elapsed)); TerminateProcess(pi.hProcess, kExitSuccess); break; } diff --git a/src/lib/platform/CMSWindowsRelauncher.h b/src/lib/platform/CMSWindowsRelauncher.h index 50e4ce912..2127234a4 100644 --- a/src/lib/platform/CMSWindowsRelauncher.h +++ b/src/lib/platform/CMSWindowsRelauncher.h @@ -24,10 +24,14 @@ class CThread; class CIpcLogOutputter; +class CIpcServer; class CMSWindowsRelauncher { public: - CMSWindowsRelauncher(bool autoDetectCommand); + CMSWindowsRelauncher( + bool autoDetectCommand, + CIpcServer& ipcServer, + CIpcLogOutputter& ipcLogOutputter); virtual ~CMSWindowsRelauncher(); void startAsync(); std::string command() const; @@ -42,9 +46,6 @@ private: void outputLoop(void*); void shutdownProcess(const PROCESS_INFORMATION& pi, int timeout); -public: - CIpcLogOutputter* m_ipcLogOutputter; - private: CThread* m_thread; bool m_autoDetectCommand; @@ -54,4 +55,6 @@ private: HANDLE m_stdOutWrite; HANDLE m_stdOutRead; CThread* m_outputThread; + CIpcServer& m_ipcServer; + CIpcLogOutputter& m_ipcLogOutputter; }; diff --git a/src/lib/platform/CMakeLists.txt b/src/lib/platform/CMakeLists.txt index bb2bd414f..e5946677a 100644 --- a/src/lib/platform/CMakeLists.txt +++ b/src/lib/platform/CMakeLists.txt @@ -138,6 +138,8 @@ set(inc ../mt ../synergy ../ipc + ../net + ../io ) if (UNIX) @@ -192,5 +194,5 @@ if (WIN32) endif() if (UNIX) - target_link_libraries(platform ipc synergy ${libs}) + target_link_libraries(platform io net ipc synergy ${libs}) endif() diff --git a/src/lib/server/CClientListener.cpp b/src/lib/server/CClientListener.cpp index 5defd9073..d4718f1d1 100644 --- a/src/lib/server/CClientListener.cpp +++ b/src/lib/server/CClientListener.cpp @@ -66,7 +66,7 @@ CClientListener::CClientListener(const CNetworkAddress& address, LOG((CLOG_DEBUG1 "listening for clients")); // setup event handler - EVENTQUEUE->adoptHandler(IListenSocket::getConnectingEvent(), m_listen, + EVENTQUEUE->adoptHandler(m_listen->getConnectingEvent(), m_listen, new TMethodEventJob(this, &CClientListener::handleClientConnecting)); } @@ -95,7 +95,7 @@ CClientListener::~CClientListener() client = getNextClient(); } - EVENTQUEUE->removeHandler(IListenSocket::getConnectingEvent(), m_listen); + EVENTQUEUE->removeHandler(m_listen->getConnectingEvent(), m_listen); delete m_listen; delete m_socketFactory; delete m_streamFilterFactory; @@ -131,7 +131,7 @@ void CClientListener::handleClientConnecting(const CEvent&, void*) { // accept client connection - IStream* stream = m_listen->accept(); + synergy::IStream* stream = m_listen->accept(); if (stream == NULL) { return; } diff --git a/src/lib/server/CClientProxy.cpp b/src/lib/server/CClientProxy.cpp index 713c87575..e923f8fe0 100644 --- a/src/lib/server/CClientProxy.cpp +++ b/src/lib/server/CClientProxy.cpp @@ -30,7 +30,7 @@ CEvent::Type CClientProxy::s_disconnectedEvent = CEvent::kUnknown; CEvent::Type CClientProxy::s_clipboardChangedEvent= CEvent::kUnknown; CEvent::Type CClientProxy::s_gameDeviceTimingRecvEvent= CEvent::kUnknown; -CClientProxy::CClientProxy(const CString& name, IStream* stream) : +CClientProxy::CClientProxy(const CString& name, synergy::IStream* stream) : CBaseClientProxy(name), m_stream(stream) { @@ -52,7 +52,7 @@ CClientProxy::close(const char* msg) getStream()->flush(); } -IStream* +synergy::IStream* CClientProxy::getStream() const { return m_stream; diff --git a/src/lib/server/CClientProxy.h b/src/lib/server/CClientProxy.h index 95a0dad40..b7f9a6ba0 100644 --- a/src/lib/server/CClientProxy.h +++ b/src/lib/server/CClientProxy.h @@ -22,7 +22,7 @@ #include "CEvent.h" #include "CString.h" -class IStream; +namespace synergy { class IStream; } //! Generic proxy for client class CClientProxy : public CBaseClientProxy { @@ -30,7 +30,7 @@ public: /*! \c name is the name of the client. */ - CClientProxy(const CString& name, IStream* adoptedStream); + CClientProxy(const CString& name, synergy::IStream* adoptedStream); ~CClientProxy(); //! @name manipulators @@ -50,7 +50,7 @@ public: /*! Returns the stream passed to the c'tor. */ - IStream* getStream() const; + synergy::IStream* getStream() const; //! Get ready event type /*! @@ -117,7 +117,7 @@ public: virtual void gameDeviceTimingReq() = 0; private: - IStream* m_stream; + synergy::IStream* m_stream; static CEvent::Type s_readyEvent; static CEvent::Type s_disconnectedEvent; diff --git a/src/lib/server/CClientProxy1_0.cpp b/src/lib/server/CClientProxy1_0.cpp index d7d3cf831..4412328fe 100644 --- a/src/lib/server/CClientProxy1_0.cpp +++ b/src/lib/server/CClientProxy1_0.cpp @@ -28,7 +28,7 @@ // CClientProxy1_0 // -CClientProxy1_0::CClientProxy1_0(const CString& name, IStream* stream) : +CClientProxy1_0::CClientProxy1_0(const CString& name, synergy::IStream* stream) : CClientProxy(name, stream), m_heartbeatTimer(NULL), m_parser(&CClientProxy1_0::parseHandshakeMessage) diff --git a/src/lib/server/CClientProxy1_0.h b/src/lib/server/CClientProxy1_0.h index b60e71132..94595060c 100644 --- a/src/lib/server/CClientProxy1_0.h +++ b/src/lib/server/CClientProxy1_0.h @@ -28,7 +28,7 @@ class CEventQueueTimer; //! Proxy for client implementing protocol version 1.0 class CClientProxy1_0 : public CClientProxy { public: - CClientProxy1_0(const CString& name, IStream* adoptedStream); + CClientProxy1_0(const CString& name, synergy::IStream* adoptedStream); ~CClientProxy1_0(); // IScreen diff --git a/src/lib/server/CClientProxy1_1.cpp b/src/lib/server/CClientProxy1_1.cpp index e07850326..d4ef1fe0b 100644 --- a/src/lib/server/CClientProxy1_1.cpp +++ b/src/lib/server/CClientProxy1_1.cpp @@ -24,7 +24,7 @@ // CClientProxy1_1 // -CClientProxy1_1::CClientProxy1_1(const CString& name, IStream* stream) : +CClientProxy1_1::CClientProxy1_1(const CString& name, synergy::IStream* stream) : CClientProxy1_0(name, stream) { // do nothing diff --git a/src/lib/server/CClientProxy1_1.h b/src/lib/server/CClientProxy1_1.h index aa1b2a7ee..a8b52856e 100644 --- a/src/lib/server/CClientProxy1_1.h +++ b/src/lib/server/CClientProxy1_1.h @@ -23,7 +23,7 @@ //! Proxy for client implementing protocol version 1.1 class CClientProxy1_1 : public CClientProxy1_0 { public: - CClientProxy1_1(const CString& name, IStream* adoptedStream); + CClientProxy1_1(const CString& name, synergy::IStream* adoptedStream); ~CClientProxy1_1(); // IClient overrides diff --git a/src/lib/server/CClientProxy1_2.cpp b/src/lib/server/CClientProxy1_2.cpp index 80e102eb7..96a21e973 100644 --- a/src/lib/server/CClientProxy1_2.cpp +++ b/src/lib/server/CClientProxy1_2.cpp @@ -23,7 +23,7 @@ // CClientProxy1_1 // -CClientProxy1_2::CClientProxy1_2(const CString& name, IStream* stream) : +CClientProxy1_2::CClientProxy1_2(const CString& name, synergy::IStream* stream) : CClientProxy1_1(name, stream) { // do nothing diff --git a/src/lib/server/CClientProxy1_2.h b/src/lib/server/CClientProxy1_2.h index 1ac9a25be..57991f148 100644 --- a/src/lib/server/CClientProxy1_2.h +++ b/src/lib/server/CClientProxy1_2.h @@ -23,7 +23,7 @@ //! Proxy for client implementing protocol version 1.2 class CClientProxy1_2 : public CClientProxy1_1 { public: - CClientProxy1_2(const CString& name, IStream* adoptedStream); + CClientProxy1_2(const CString& name, synergy::IStream* adoptedStream); ~CClientProxy1_2(); // IClient overrides diff --git a/src/lib/server/CClientProxy1_3.cpp b/src/lib/server/CClientProxy1_3.cpp index 97c56e77f..4406576d9 100644 --- a/src/lib/server/CClientProxy1_3.cpp +++ b/src/lib/server/CClientProxy1_3.cpp @@ -27,7 +27,7 @@ // CClientProxy1_3 // -CClientProxy1_3::CClientProxy1_3(const CString& name, IStream* stream) : +CClientProxy1_3::CClientProxy1_3(const CString& name, synergy::IStream* stream) : CClientProxy1_2(name, stream), m_keepAliveRate(kKeepAliveRate), m_keepAliveTimer(NULL) diff --git a/src/lib/server/CClientProxy1_3.h b/src/lib/server/CClientProxy1_3.h index 22f5ae3b0..7bcb5e7dc 100644 --- a/src/lib/server/CClientProxy1_3.h +++ b/src/lib/server/CClientProxy1_3.h @@ -23,7 +23,7 @@ //! Proxy for client implementing protocol version 1.3 class CClientProxy1_3 : public CClientProxy1_2 { public: - CClientProxy1_3(const CString& name, IStream* adoptedStream); + CClientProxy1_3(const CString& name, synergy::IStream* adoptedStream); ~CClientProxy1_3(); // IClient overrides diff --git a/src/lib/server/CClientProxy1_4.cpp b/src/lib/server/CClientProxy1_4.cpp index 6f0b2d8a4..a36d3c2aa 100644 --- a/src/lib/server/CClientProxy1_4.cpp +++ b/src/lib/server/CClientProxy1_4.cpp @@ -28,7 +28,7 @@ // CClientProxy1_4 // -CClientProxy1_4::CClientProxy1_4(const CString& name, IStream* stream, CServer* server) : +CClientProxy1_4::CClientProxy1_4(const CString& name, synergy::IStream* stream, CServer* server) : CClientProxy1_3(name, stream), m_server(server) { assert(m_server != NULL); diff --git a/src/lib/server/CClientProxy1_4.h b/src/lib/server/CClientProxy1_4.h index 0da559ca1..44d3ac95f 100644 --- a/src/lib/server/CClientProxy1_4.h +++ b/src/lib/server/CClientProxy1_4.h @@ -25,7 +25,7 @@ class CServer; //! Proxy for client implementing protocol version 1.4 class CClientProxy1_4 : public CClientProxy1_3 { public: - CClientProxy1_4(const CString& name, IStream* adoptedStream, CServer* server); + CClientProxy1_4(const CString& name, synergy::IStream* adoptedStream, CServer* server); ~CClientProxy1_4(); // IClient overrides diff --git a/src/lib/server/CClientProxyUnknown.cpp b/src/lib/server/CClientProxyUnknown.cpp index 2965d93c0..2732d868c 100644 --- a/src/lib/server/CClientProxyUnknown.cpp +++ b/src/lib/server/CClientProxyUnknown.cpp @@ -39,7 +39,7 @@ CEvent::Type CClientProxyUnknown::s_successEvent = CEvent::kUnknown; CEvent::Type CClientProxyUnknown::s_failureEvent = CEvent::kUnknown; -CClientProxyUnknown::CClientProxyUnknown(IStream* stream, double timeout, CServer* server) : +CClientProxyUnknown::CClientProxyUnknown(synergy::IStream* stream, double timeout, CServer* server) : m_stream(stream), m_proxy(NULL), m_ready(false), diff --git a/src/lib/server/CClientProxyUnknown.h b/src/lib/server/CClientProxyUnknown.h index 7c8dad728..23387c96d 100644 --- a/src/lib/server/CClientProxyUnknown.h +++ b/src/lib/server/CClientProxyUnknown.h @@ -22,12 +22,12 @@ class CClientProxy; class CEventQueueTimer; -class IStream; +namespace synergy { class IStream; } class CServer; class CClientProxyUnknown { public: - CClientProxyUnknown(IStream* stream, double timeout, CServer* server); + CClientProxyUnknown(synergy::IStream* stream, double timeout, CServer* server); ~CClientProxyUnknown(); //! @name manipulators @@ -75,7 +75,7 @@ private: void handleReady(const CEvent&, void*); private: - IStream* m_stream; + synergy::IStream* m_stream; CEventQueueTimer* m_timer; CClientProxy* m_proxy; bool m_ready; diff --git a/src/lib/synergy/CApp.cpp b/src/lib/synergy/CApp.cpp index a85cc5cf1..0063089d1 100644 --- a/src/lib/synergy/CApp.cpp +++ b/src/lib/synergy/CApp.cpp @@ -25,6 +25,10 @@ #include "LogOutputters.h" #include "XSynergy.h" #include "CArgsBase.h" +#include "CIpcServerProxy.h" +#include "TMethodEventJob.h" +#include "CIpcMessage.h" +#include "Ipc.h" #if SYSAPI_WIN32 #include "CArchMiscWindows.h" @@ -46,7 +50,8 @@ m_createTaskBarReceiver(createTaskBarReceiver), m_args(args), m_bye(&exit), m_taskBarReceiver(NULL), -m_suspended(false) +m_suspended(false), +m_ipcClient(nullptr) { assert(s_instance == nullptr); s_instance = this; @@ -142,6 +147,10 @@ CApp::parseArg(const int& argc, const char* const* argv, int& i) argsBase().m_disableTray = true; } + else if (isArg(i, argc, argv, NULL, "--ipc")) { + argsBase().m_enableIpc = true; + } + #if VNC_SUPPORT else if (isArg(i, argc, argv, NULL, "--vnc")) { argsBase().m_enableVnc = true; @@ -335,3 +344,33 @@ CApp::initApp(int argc, const char** argv) m_taskBarReceiver = m_createTaskBarReceiver(logBuffer); } } + +void +CApp::initIpcClient() +{ + // TODO: delete ipc client on shutdown and the 2 event handlers. + m_ipcClient = new CIpcClient(); + m_ipcClient->connect(); + + EVENTQUEUE->adoptHandler( + CIpcClient::getConnectedEvent(), m_ipcClient, + new TMethodEventJob(this, &CApp::handleIpcConnected)); +} + +void +CApp::handleIpcConnected(const CEvent& e, void*) +{ + EVENTQUEUE->adoptHandler( + CIpcServerProxy::getMessageReceivedEvent(), e.getData(), + new TMethodEventJob(this, &CApp::handleIpcMessage)); +} + +void +CApp::handleIpcMessage(const CEvent& e, void*) +{ + CIpcMessage* m = static_cast(e.getData()); + if (m->m_type == kIpcShutdown) { + LOG((CLOG_INFO "got ipc shutdown message")); + EVENTQUEUE->addEvent(CEvent(CEvent::kQuit)); + } +} diff --git a/src/lib/synergy/CApp.h b/src/lib/synergy/CApp.h index 2fe4234a4..ce229fa05 100644 --- a/src/lib/synergy/CApp.h +++ b/src/lib/synergy/CApp.h @@ -20,6 +20,7 @@ #include "common.h" #include "CString.h" #include "IApp.h" +#include "CIpcClient.h" #if SYSAPI_WIN32 #include "CAppUtilWindows.h" @@ -92,9 +93,14 @@ public: virtual void setByeFunc(void(*bye)(int)) { m_bye = bye; } virtual void bye(int error) { m_bye(error); } +private: + void handleIpcConnected(const CEvent&, void*); + void handleIpcMessage(const CEvent&, void*); + protected: virtual void parseArgs(int argc, const char* const* argv, int &i); virtual bool parseArg(const int& argc, const char* const* argv, int& i); + void initIpcClient(); IArchTaskBarReceiver* m_taskBarReceiver; bool m_suspended; @@ -105,6 +111,7 @@ private: CFileLogOutputter* m_fileLog; CreateTaskBarReceiverFunc m_createTaskBarReceiver; ARCH_APP_UTIL m_appUtil; + CIpcClient* m_ipcClient; }; #define BYE "\nTry `%s --help' for more information." diff --git a/src/lib/synergy/CAppUtilWindows.cpp b/src/lib/synergy/CAppUtilWindows.cpp index 32048b862..a48bc397a 100644 --- a/src/lib/synergy/CAppUtilWindows.cpp +++ b/src/lib/synergy/CAppUtilWindows.cpp @@ -25,7 +25,6 @@ #include "CMSWindowsScreen.h" #include "XSynergy.h" #include "IArchTaskBarReceiver.h" -#include "CMSWindowsRelauncher.h" #include "CScreen.h" #include "CArgsBase.h" #include "IEventQueue.h" @@ -214,17 +213,5 @@ CAppUtilWindows::debugServiceWait() void CAppUtilWindows::startNode() { - if (app().argsBase().m_relaunchMode) { - - LOG((CLOG_DEBUG1 "entering relaunch mode")); - CMSWindowsRelauncher relauncher(true); - relauncher.startAsync(); - - // HACK: create a dummy screen, which can handle system events - // (such as a stop request from the service controller). - CScreen* dummyScreen = app().createScreen(); - } - else { - app().startNode(); - } + app().startNode(); } diff --git a/src/lib/synergy/CArgsBase.cpp b/src/lib/synergy/CArgsBase.cpp index 0871047aa..5d6f60c87 100644 --- a/src/lib/synergy/CArgsBase.cpp +++ b/src/lib/synergy/CArgsBase.cpp @@ -21,7 +21,6 @@ CArgsBase::CArgsBase() : #if SYSAPI_WIN32 m_daemon(false), // daemon mode not supported on windows (use --service) m_debugServiceWait(false), -m_relaunchMode(false), m_pauseOnExit(false), #else m_daemon(true), // backward compatibility for unix (daemon by default) diff --git a/src/lib/synergy/CArgsBase.h b/src/lib/synergy/CArgsBase.h index f3f5b5879..4582e5199 100644 --- a/src/lib/synergy/CArgsBase.h +++ b/src/lib/synergy/CArgsBase.h @@ -35,8 +35,8 @@ public: CString m_name; bool m_disableTray; bool m_enableVnc; + bool m_enableIpc; #if SYSAPI_WIN32 - bool m_relaunchMode; bool m_debugServiceWait; bool m_pauseOnExit; CGameDeviceInfo m_gameDevice; diff --git a/src/lib/synergy/CClientApp.cpp b/src/lib/synergy/CClientApp.cpp index 01e6985be..a3d567458 100644 --- a/src/lib/synergy/CClientApp.cpp +++ b/src/lib/synergy/CClientApp.cpp @@ -528,6 +528,10 @@ CClientApp::mainLoop() // create the event queue CEventQueue eventQueue; + + if (argsBase().m_enableIpc) { + initIpcClient(); + } // start client, etc appUtil().startNode(); diff --git a/src/lib/synergy/CDaemonApp.cpp b/src/lib/synergy/CDaemonApp.cpp index ebc5192a3..842421251 100644 --- a/src/lib/synergy/CDaemonApp.cpp +++ b/src/lib/synergy/CDaemonApp.cpp @@ -78,7 +78,7 @@ CDaemonApp::CDaemonApp() : m_ipcServer(nullptr), m_ipcLogOutputter(nullptr) #if SYSAPI_WIN32 -,m_relauncher(false) +,m_relauncher(nullptr) #endif { s_instance = this; @@ -182,16 +182,20 @@ CDaemonApp::mainLoop(bool logToFile) // uses event queue, must be created here. m_ipcServer = new CIpcServer(); + // send logging to gui via ipc, log system adopts outputter. + m_ipcLogOutputter = new CIpcLogOutputter(*m_ipcServer); + CLOG->insert(m_ipcLogOutputter); + +#if SYSAPI_WIN32 + m_relauncher = new CMSWindowsRelauncher(false, *m_ipcServer, *m_ipcLogOutputter); +#endif + eventQueue.adoptHandler( CIpcServer::getClientConnectedEvent(), m_ipcServer, new TMethodEventJob(this, &CDaemonApp::handleIpcConnected)); m_ipcServer->listen(); - // send logging to gui via ipc, log system adopts outputter. - m_ipcLogOutputter = new CIpcLogOutputter(*m_ipcServer); - CLOG->insert(m_ipcLogOutputter); - #if SYSAPI_WIN32 // HACK: create a dummy screen, which can handle system events // (such as a stop request from the service controller). @@ -199,21 +203,19 @@ CDaemonApp::mainLoop(bool logToFile) CGameDeviceInfo gameDevice; CScreen dummyScreen(new CMSWindowsScreen(false, true, gameDevice)); - m_relauncher.m_ipcLogOutputter = m_ipcLogOutputter; - string command = ARCH->setting("Command"); if (command != "") { LOG((CLOG_INFO "using last known command: %s", command.c_str())); - m_relauncher.command(command); + m_relauncher->command(command); } - m_relauncher.startAsync(); + m_relauncher->startAsync(); #endif eventQueue.loop(); #if SYSAPI_WIN32 - m_relauncher.stop(); + m_relauncher->stop(); #endif eventQueue.removeHandler( @@ -275,13 +277,12 @@ CDaemonApp::handleIpcConnected(const CEvent& e, void*) void CDaemonApp::handleIpcMessage(const CEvent& e, void*) { - CIpcMessage& m = *reinterpret_cast(e.getData()); - + CIpcMessage& m = *static_cast(e.getData()); LOG((CLOG_DEBUG "ipc message, type=%d", m.m_type)); switch (m.m_type) { case kIpcCommand: { - CString& command = *reinterpret_cast(m.m_data); + CString& command = *static_cast(m.m_data); LOG((CLOG_DEBUG "got new command: %s", command.c_str())); try { @@ -296,7 +297,7 @@ CDaemonApp::handleIpcMessage(const CEvent& e, void*) // tell the relauncher about the new command. this causes the // relauncher to stop the existing command and start the new // command. - m_relauncher.command(command); + m_relauncher->command(command); } break; diff --git a/src/lib/synergy/CDaemonApp.h b/src/lib/synergy/CDaemonApp.h index 2c9ecb8f3..54dbd6a12 100644 --- a/src/lib/synergy/CDaemonApp.h +++ b/src/lib/synergy/CDaemonApp.h @@ -48,7 +48,8 @@ public: static CDaemonApp* s_instance; #if SYSAPI_WIN32 - CMSWindowsRelauncher m_relauncher; + CMSWindowsRelauncher* + m_relauncher; #endif private: @@ -57,7 +58,3 @@ private: }; #define LOG_FILENAME "synergyd.log" - -enum { - kIpcCommand = 1 -}; diff --git a/src/lib/synergy/CPacketStreamFilter.cpp b/src/lib/synergy/CPacketStreamFilter.cpp index a37d58727..10b5d734c 100644 --- a/src/lib/synergy/CPacketStreamFilter.cpp +++ b/src/lib/synergy/CPacketStreamFilter.cpp @@ -26,7 +26,7 @@ // CPacketStreamFilter // -CPacketStreamFilter::CPacketStreamFilter(IStream* stream, bool adoptStream) : +CPacketStreamFilter::CPacketStreamFilter(synergy::IStream* stream, bool adoptStream) : CStreamFilter(stream, adoptStream), m_size(0), m_inputShutdown(false) diff --git a/src/lib/synergy/CPacketStreamFilter.h b/src/lib/synergy/CPacketStreamFilter.h index 16d23b939..b0a3a4082 100644 --- a/src/lib/synergy/CPacketStreamFilter.h +++ b/src/lib/synergy/CPacketStreamFilter.h @@ -28,7 +28,7 @@ Filters a stream to read and write packets. */ class CPacketStreamFilter : public CStreamFilter { public: - CPacketStreamFilter(IStream* stream, bool adoptStream = true); + CPacketStreamFilter(synergy::IStream* stream, bool adoptStream = true); ~CPacketStreamFilter(); // IStream overrides diff --git a/src/lib/synergy/CProtocolUtil.cpp b/src/lib/synergy/CProtocolUtil.cpp index ecda7ba8f..517d80821 100644 --- a/src/lib/synergy/CProtocolUtil.cpp +++ b/src/lib/synergy/CProtocolUtil.cpp @@ -27,7 +27,7 @@ // void -CProtocolUtil::writef(IStream* stream, const char* fmt, ...) +CProtocolUtil::writef(synergy::IStream* stream, const char* fmt, ...) { assert(stream != NULL); assert(fmt != NULL); @@ -43,7 +43,7 @@ CProtocolUtil::writef(IStream* stream, const char* fmt, ...) } bool -CProtocolUtil::readf(IStream* stream, const char* fmt, ...) +CProtocolUtil::readf(synergy::IStream* stream, const char* fmt, ...) { assert(stream != NULL); assert(fmt != NULL); @@ -64,7 +64,7 @@ CProtocolUtil::readf(IStream* stream, const char* fmt, ...) } void -CProtocolUtil::vwritef(IStream* stream, +CProtocolUtil::vwritef(synergy::IStream* stream, const char* fmt, UInt32 size, va_list args) { assert(stream != NULL); @@ -93,7 +93,7 @@ CProtocolUtil::vwritef(IStream* stream, } void -CProtocolUtil::vreadf(IStream* stream, const char* fmt, va_list args) +CProtocolUtil::vreadf(synergy::IStream* stream, const char* fmt, va_list args) { assert(stream != NULL); assert(fmt != NULL); @@ -507,7 +507,7 @@ CProtocolUtil::eatLength(const char** pfmt) } void -CProtocolUtil::read(IStream* stream, void* vbuffer, UInt32 count) +CProtocolUtil::read(synergy::IStream* stream, void* vbuffer, UInt32 count) { assert(stream != NULL); assert(vbuffer != NULL); diff --git a/src/lib/synergy/CProtocolUtil.h b/src/lib/synergy/CProtocolUtil.h index 1d5494fd4..085e71474 100644 --- a/src/lib/synergy/CProtocolUtil.h +++ b/src/lib/synergy/CProtocolUtil.h @@ -22,7 +22,7 @@ #include "XIO.h" #include -class IStream; +namespace synergy { class IStream; } //! Synergy protocol utilities /*! @@ -49,7 +49,7 @@ public: - \%s -- converts CString* to stream of bytes - \%S -- converts integer N and const UInt8* to stream of N bytes */ - static void writef(IStream*, + static void writef(synergy::IStream*, const char* fmt, ...); //! Read formatted data @@ -68,19 +68,19 @@ public: - \%4I -- reads NBO 4 byte integers; arg is std::vector* - \%s -- reads bytes; argument must be a CString*, \b not a char* */ - static bool readf(IStream*, + static bool readf(synergy::IStream*, const char* fmt, ...); private: - static void vwritef(IStream*, + static void vwritef(synergy::IStream*, const char* fmt, UInt32 size, va_list); - static void vreadf(IStream*, + static void vreadf(synergy::IStream*, const char* fmt, va_list); static UInt32 getLength(const char* fmt, va_list); static void writef(void*, const char* fmt, va_list); static UInt32 eatLength(const char** fmt); - static void read(IStream*, void*, UInt32); + static void read(synergy::IStream*, void*, UInt32); }; //! Mismatched read exception diff --git a/src/lib/synergy/CServerApp.cpp b/src/lib/synergy/CServerApp.cpp index 4ee3eeb4c..35a2d80e1 100644 --- a/src/lib/synergy/CServerApp.cpp +++ b/src/lib/synergy/CServerApp.cpp @@ -760,6 +760,15 @@ CServerApp::mainLoop() // create the event queue CEventQueue eventQueue; +/* + bool a = true; + while (a) { + ARCH->sleep(1); + }*/ + + if (argsBase().m_enableIpc) { + initIpcClient(); + } // if configuration has no screens then add this system // as the default diff --git a/src/test/integtests/CIpcTests.cpp b/src/test/integtests/CIpcTests.cpp index 8728a497a..b3ee8c065 100644 --- a/src/test/integtests/CIpcTests.cpp +++ b/src/test/integtests/CIpcTests.cpp @@ -59,8 +59,8 @@ public: bool m_connectToServer_clientConnected; CString m_sendMessageToServer_receivedString; CString m_sendMessageToClient_receivedString; + CIpcClient* m_sendMessageToServer_client; CIpcServer* m_sendMessageToClient_server; - CIpcServerProxy* m_sendMessageToClient_serverProxy; }; TEST_F(CIpcTests, connectToServer) @@ -89,16 +89,13 @@ TEST_F(CIpcTests, sendMessageToServer) CIpcClient client; client.connect(); + m_sendMessageToServer_client = &client; + // event handler sends "test" log line to client. m_events.adoptHandler( CIpcServer::getClientConnectedEvent(), &server, new TMethodEventJob( this, &CIpcTests::sendMessageToServer_handleClientConnected)); - - CIpcMessage m; - m.m_type = kIpcCommand; - m.m_data = (void*)(new CString("test")); - client.send(m); quitTimeout(2); m_events.loop(); @@ -114,11 +111,10 @@ TEST_F(CIpcTests, sendMessageToClient) CIpcClient client; client.connect(); - m_sendMessageToClient_serverProxy = client.m_server; - // event handler sends "test" log line to client. + // event handler sends "test" log line to server. m_events.adoptHandler( - CIpcServer::getClientConnectedEvent(), &server, + CIpcClient::getConnectedEvent(), &client, new TMethodEventJob( this, &CIpcTests::sendMessageToClient_handleConnected)); @@ -131,7 +127,7 @@ TEST_F(CIpcTests, sendMessageToClient) CIpcTests::CIpcTests() : m_connectToServer_clientConnected(false), m_sendMessageToClient_server(nullptr), -m_sendMessageToClient_serverProxy(nullptr) +m_sendMessageToServer_client(nullptr) { } @@ -153,36 +149,45 @@ CIpcTests::sendMessageToServer_handleClientConnected(const CEvent& e, void*) CIpcClientProxy::getMessageReceivedEvent(), e.getData(), new TMethodEventJob( this, &CIpcTests::sendMessageToServer_handleMessageReceived)); + + CIpcMessage m; + m.m_type = kIpcCommand; + m.m_data = new CString("test"); + m_sendMessageToServer_client->send(m); } void CIpcTests::sendMessageToServer_handleMessageReceived(const CEvent& e, void*) { - CIpcMessage* m = (CIpcMessage*)e.getData(); - m_sendMessageToServer_receivedString = *((CString*)m->m_data); - raiseQuitEvent(); + CIpcMessage* m = static_cast(e.getData()); + if (m->m_type == kIpcCommand) { + m_sendMessageToServer_receivedString = *static_cast(m->m_data); + raiseQuitEvent(); + } } void CIpcTests::sendMessageToClient_handleConnected(const CEvent& e, void*) { m_events.adoptHandler( - CIpcServerProxy::getMessageReceivedEvent(), m_sendMessageToClient_serverProxy, + CIpcServerProxy::getMessageReceivedEvent(), e.getData(), new TMethodEventJob( this, &CIpcTests::sendMessageToClient_handleMessageReceived)); CIpcMessage m; m.m_type = kIpcLogLine; - m.m_data = (void*)(new CString("test")); - m_sendMessageToClient_server->send(m); + m.m_data = new CString("test"); + m_sendMessageToClient_server->send(m, kIpcClientUnknown); } void CIpcTests::sendMessageToClient_handleMessageReceived(const CEvent& e, void*) { - CIpcMessage* m = reinterpret_cast(e.getData()); - m_sendMessageToClient_receivedString = *((CString*)m->m_data); - raiseQuitEvent(); + CIpcMessage* m = static_cast(e.getData()); + if (m->m_type == kIpcLogLine) { + m_sendMessageToClient_receivedString = *static_cast(m->m_data); + raiseQuitEvent(); + } } void diff --git a/src/test/unittests/io/CMockStream.h b/src/test/unittests/io/CMockStream.h index 7d75ee34b..2e69a639b 100644 --- a/src/test/unittests/io/CMockStream.h +++ b/src/test/unittests/io/CMockStream.h @@ -22,7 +22,7 @@ class IEventQueue; -class CMockStream : public IStream +class CMockStream : public synergy::IStream { public: CMockStream(IEventQueue& eventQueue) : IStream(eventQueue) { }