diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp index 5919dab7..ff57d540 100644 --- a/src/lib/client/Client.cpp +++ b/src/lib/client/Client.cpp @@ -265,7 +265,11 @@ Client::leave() m_screen->leave(); m_active = false; - + + if (m_sendClipboardThread != NULL) { + StreamChunker::interruptClipboard(); + } + m_sendClipboardThread = new Thread( new TMethodJob( this, @@ -803,6 +807,10 @@ Client::isReceivedFileSizeValid() void Client::sendFileToServer(const char* filename) { + if (m_sendFileThread != NULL) { + StreamChunker::interruptFile(); + } + m_sendFileThread = new Thread( new TMethodJob( this, &Client::sendFileThread, diff --git a/src/lib/server/Server.cpp b/src/lib/server/Server.cpp index 8c0574ef..832a03b0 100644 --- a/src/lib/server/Server.cpp +++ b/src/lib/server/Server.cpp @@ -505,7 +505,12 @@ Server::switchScreen(BaseClientProxy* dst, m_active->enter(x, y, m_seqNum, m_primaryClient->getToggleMask(), forScreensaver); - + // if already sending clipboard, we need to interupt it, otherwise + // clipboard data could be corrupted on the other side + if (m_sendClipboardThread != NULL) { + StreamChunker::interruptClipboard(); + } + // send the clipboard data to new active screen m_sendClipboardThread = new Thread( new TMethodJob( @@ -2347,6 +2352,10 @@ Server::isReceivedFileSizeValid() void Server::sendFileToClient(const char* filename) { + if (m_sendFileThread != NULL) { + StreamChunker::interruptFile(); + } + m_sendFileThread = new Thread( new TMethodJob( this, &Server::sendFileThread, diff --git a/src/lib/synergy/StreamChunker.cpp b/src/lib/synergy/StreamChunker.cpp index 4058385e..46230ccd 100644 --- a/src/lib/synergy/StreamChunker.cpp +++ b/src/lib/synergy/StreamChunker.cpp @@ -39,6 +39,11 @@ using namespace std; #define SECURE_SOCKET_CHUNK_SIZE 2 * 1024; // 2kb size_t StreamChunker::s_chunkSize = SOCKET_CHUNK_SIZE; +bool StreamChunker::s_isChunkingClipboard = false; +bool StreamChunker::s_interruptClipboard = false; +bool StreamChunker::s_isChunkingFile = false; +bool StreamChunker::s_interruptFile = false; + void StreamChunker::sendFile( @@ -46,6 +51,8 @@ StreamChunker::sendFile( IEventQueue* events, void* eventTarget) { + s_isChunkingFile = true; + std::fstream file(reinterpret_cast(filename), std::ios::in | std::ios::binary); if (!file.is_open()) { @@ -69,6 +76,11 @@ StreamChunker::sendFile( stopwatch.start(); file.seekg (0, std::ios::beg); while (true) { + if (s_interruptFile) { + s_interruptFile = false; + break; + } + if (stopwatch.getTime() > PAUSE_TIME_HACK) { // make sure we don't read too much from the mock data. if (sentLength + chunkSize > size) { @@ -100,6 +112,8 @@ StreamChunker::sendFile( events->addEvent(Event(events->forIScreen().fileChunkSending(), eventTarget, end)); file.close(); + + s_isChunkingFile = false; } void @@ -111,6 +125,8 @@ StreamChunker::sendClipboard( IEventQueue* events, void* eventTarget) { + s_isChunkingClipboard = true; + // send first message (data size) String dataSize = synergy::string::sizeTypeToString(size); ClipboardChunk* sizeMessage = ClipboardChunk::start(id, sequence, dataSize); @@ -122,7 +138,13 @@ StreamChunker::sendClipboard( size_t chunkSize = s_chunkSize; Stopwatch stopwatch; stopwatch.start(); + while (true) { + if (s_interruptClipboard) { + s_interruptClipboard = false; + break; + } + if (stopwatch.getTime() > 0.1f) { // make sure we don't read too much from the mock data. if (sentLength + chunkSize > size) { @@ -148,6 +170,8 @@ StreamChunker::sendClipboard( ClipboardChunk* end = ClipboardChunk::end(id, sequence); events->addEvent(Event(events->forClipboard().clipboardSending(), eventTarget, end)); + + s_isChunkingClipboard = false; } void @@ -160,3 +184,21 @@ StreamChunker::updateChunkSize(bool useSecureSocket) s_chunkSize = SOCKET_CHUNK_SIZE; } } + +void +StreamChunker::interruptFile() +{ + if (s_isChunkingFile) { + s_interruptFile = true; + LOG((CLOG_INFO "previous dragged file has become invalid")); + } +} + +void +StreamChunker::interruptClipboard() +{ + if (s_isChunkingClipboard) { + s_interruptClipboard = true; + LOG((CLOG_INFO "previous clipboard data has become invalid")); + } +} diff --git a/src/lib/synergy/StreamChunker.h b/src/lib/synergy/StreamChunker.h index a4be2714..b0bfb341 100644 --- a/src/lib/synergy/StreamChunker.h +++ b/src/lib/synergy/StreamChunker.h @@ -36,7 +36,13 @@ public: IEventQueue* events, void* eventTarget); static void updateChunkSize(bool useSecureSocket); - + static void interruptFile(); + static void interruptClipboard(); + private: - static size_t s_chunkSize; + static size_t s_chunkSize; + static bool s_isChunkingClipboard; + static bool s_interruptClipboard; + static bool s_isChunkingFile; + static bool s_interruptFile; };