diff options
Diffstat (limited to 'common/rfb/DecodeManager.cxx')
-rw-r--r-- | common/rfb/DecodeManager.cxx | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/common/rfb/DecodeManager.cxx b/common/rfb/DecodeManager.cxx index 724cf215..d6c3b0b5 100644 --- a/common/rfb/DecodeManager.cxx +++ b/common/rfb/DecodeManager.cxx @@ -36,7 +36,7 @@ using namespace rfb; static LogWriter vlog("DecodeManager"); DecodeManager::DecodeManager(CConnection *conn) : - conn(conn) + conn(conn), threadException(NULL) { size_t cpuCount; @@ -71,6 +71,8 @@ DecodeManager::~DecodeManager() threads.pop_back(); } + delete threadException; + while (!freeBuffers.empty()) { delete freeBuffers.back(); freeBuffers.pop_back(); @@ -121,6 +123,9 @@ void DecodeManager::decodeRect(const Rect& r, int encoding, queueMutex->unlock(); + // First check if any thread has encountered a problem + throwThreadException(); + // Read the rect bufferStream->clear(); decoder->readRect(r, conn->getInStream(), conn->cp, bufferStream); @@ -163,6 +168,33 @@ void DecodeManager::flush() producerCond->wait(); queueMutex->unlock(); + + throwThreadException(); +} + +void DecodeManager::setThreadException(const rdr::Exception& e) +{ + os::AutoMutex a(queueMutex); + + if (threadException == NULL) + return; + + threadException = new rdr::Exception("Exception on worker thread: %s", e.str()); +} + +void DecodeManager::throwThreadException() +{ + os::AutoMutex a(queueMutex); + + if (threadException == NULL) + return; + + rdr::Exception e(*threadException); + + delete threadException; + threadException = NULL; + + throw e; } DecodeManager::DecodeThread::DecodeThread(DecodeManager* manager) @@ -218,8 +250,9 @@ void DecodeManager::DecodeThread::worker() entry->decoder->decodeRect(entry->rect, entry->bufferStream->data(), entry->bufferStream->length(), *entry->cp, entry->pb); + } catch (rdr::Exception e) { + manager->setThreadException(e); } catch(...) { - // FIXME: Try to get the exception back to the main thread assert(false); } |