Browse Source

Propagate exceptions from worker threads back to main thread

tags/v1.6.90
Pierre Ossman 8 years ago
parent
commit
0560465250
2 changed files with 44 additions and 3 deletions
  1. 35
    2
      common/rfb/DecodeManager.cxx
  2. 9
    1
      common/rfb/DecodeManager.h

+ 35
- 2
common/rfb/DecodeManager.cxx View File

@@ -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);
}


+ 9
- 1
common/rfb/DecodeManager.h View File

@@ -31,7 +31,10 @@ namespace os {
class Mutex;
}

namespace rdr { class MemOutStream; }
namespace rdr {
class Exception;
class MemOutStream;
}

namespace rfb {
class CConnection;
@@ -49,6 +52,10 @@ namespace rfb {

void flush();

private:
void setThreadException(const rdr::Exception& e);
void throwThreadException();

private:
CConnection *conn;
Decoder *decoders[encodingMax+1];
@@ -90,6 +97,7 @@ namespace rfb {
};

std::list<DecodeThread*> threads;
rdr::Exception *threadException;
};
}


Loading…
Cancel
Save