Added a way to interrupt sending clipboard/file #4601

This commit is contained in:
Xinyu Hou 2015-05-23 00:34:00 +01:00
parent ff9ad5554a
commit fb3252efef
4 changed files with 69 additions and 4 deletions

View File

@ -266,6 +266,10 @@ Client::leave()
m_active = false; m_active = false;
if (m_sendClipboardThread != NULL) {
StreamChunker::interruptClipboard();
}
m_sendClipboardThread = new Thread( m_sendClipboardThread = new Thread(
new TMethodJob<Client>( new TMethodJob<Client>(
this, this,
@ -803,6 +807,10 @@ Client::isReceivedFileSizeValid()
void void
Client::sendFileToServer(const char* filename) Client::sendFileToServer(const char* filename)
{ {
if (m_sendFileThread != NULL) {
StreamChunker::interruptFile();
}
m_sendFileThread = new Thread( m_sendFileThread = new Thread(
new TMethodJob<Client>( new TMethodJob<Client>(
this, &Client::sendFileThread, this, &Client::sendFileThread,

View File

@ -505,6 +505,11 @@ Server::switchScreen(BaseClientProxy* dst,
m_active->enter(x, y, m_seqNum, m_active->enter(x, y, m_seqNum,
m_primaryClient->getToggleMask(), m_primaryClient->getToggleMask(),
forScreensaver); 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 // send the clipboard data to new active screen
m_sendClipboardThread = new Thread( m_sendClipboardThread = new Thread(
@ -2347,6 +2352,10 @@ Server::isReceivedFileSizeValid()
void void
Server::sendFileToClient(const char* filename) Server::sendFileToClient(const char* filename)
{ {
if (m_sendFileThread != NULL) {
StreamChunker::interruptFile();
}
m_sendFileThread = new Thread( m_sendFileThread = new Thread(
new TMethodJob<Server>( new TMethodJob<Server>(
this, &Server::sendFileThread, this, &Server::sendFileThread,

View File

@ -39,6 +39,11 @@ using namespace std;
#define SECURE_SOCKET_CHUNK_SIZE 2 * 1024; // 2kb #define SECURE_SOCKET_CHUNK_SIZE 2 * 1024; // 2kb
size_t StreamChunker::s_chunkSize = SOCKET_CHUNK_SIZE; 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 void
StreamChunker::sendFile( StreamChunker::sendFile(
@ -46,6 +51,8 @@ StreamChunker::sendFile(
IEventQueue* events, IEventQueue* events,
void* eventTarget) void* eventTarget)
{ {
s_isChunkingFile = true;
std::fstream file(reinterpret_cast<char*>(filename), std::ios::in | std::ios::binary); std::fstream file(reinterpret_cast<char*>(filename), std::ios::in | std::ios::binary);
if (!file.is_open()) { if (!file.is_open()) {
@ -69,6 +76,11 @@ StreamChunker::sendFile(
stopwatch.start(); stopwatch.start();
file.seekg (0, std::ios::beg); file.seekg (0, std::ios::beg);
while (true) { while (true) {
if (s_interruptFile) {
s_interruptFile = false;
break;
}
if (stopwatch.getTime() > PAUSE_TIME_HACK) { if (stopwatch.getTime() > PAUSE_TIME_HACK) {
// make sure we don't read too much from the mock data. // make sure we don't read too much from the mock data.
if (sentLength + chunkSize > size) { if (sentLength + chunkSize > size) {
@ -100,6 +112,8 @@ StreamChunker::sendFile(
events->addEvent(Event(events->forIScreen().fileChunkSending(), eventTarget, end)); events->addEvent(Event(events->forIScreen().fileChunkSending(), eventTarget, end));
file.close(); file.close();
s_isChunkingFile = false;
} }
void void
@ -111,6 +125,8 @@ StreamChunker::sendClipboard(
IEventQueue* events, IEventQueue* events,
void* eventTarget) void* eventTarget)
{ {
s_isChunkingClipboard = true;
// send first message (data size) // send first message (data size)
String dataSize = synergy::string::sizeTypeToString(size); String dataSize = synergy::string::sizeTypeToString(size);
ClipboardChunk* sizeMessage = ClipboardChunk::start(id, sequence, dataSize); ClipboardChunk* sizeMessage = ClipboardChunk::start(id, sequence, dataSize);
@ -122,7 +138,13 @@ StreamChunker::sendClipboard(
size_t chunkSize = s_chunkSize; size_t chunkSize = s_chunkSize;
Stopwatch stopwatch; Stopwatch stopwatch;
stopwatch.start(); stopwatch.start();
while (true) { while (true) {
if (s_interruptClipboard) {
s_interruptClipboard = false;
break;
}
if (stopwatch.getTime() > 0.1f) { if (stopwatch.getTime() > 0.1f) {
// make sure we don't read too much from the mock data. // make sure we don't read too much from the mock data.
if (sentLength + chunkSize > size) { if (sentLength + chunkSize > size) {
@ -148,6 +170,8 @@ StreamChunker::sendClipboard(
ClipboardChunk* end = ClipboardChunk::end(id, sequence); ClipboardChunk* end = ClipboardChunk::end(id, sequence);
events->addEvent(Event(events->forClipboard().clipboardSending(), eventTarget, end)); events->addEvent(Event(events->forClipboard().clipboardSending(), eventTarget, end));
s_isChunkingClipboard = false;
} }
void void
@ -160,3 +184,21 @@ StreamChunker::updateChunkSize(bool useSecureSocket)
s_chunkSize = SOCKET_CHUNK_SIZE; 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"));
}
}

View File

@ -36,7 +36,13 @@ public:
IEventQueue* events, IEventQueue* events,
void* eventTarget); void* eventTarget);
static void updateChunkSize(bool useSecureSocket); static void updateChunkSize(bool useSecureSocket);
static void interruptFile();
static void interruptClipboard();
private: 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;
}; };