summaryrefslogtreecommitdiffstats
path: root/common/rfb/DecodeManager.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'common/rfb/DecodeManager.cxx')
-rw-r--r--common/rfb/DecodeManager.cxx37
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);
}