From b487c8b74252ac995d183da8908414238b00cb72 Mon Sep 17 00:00:00 2001 From: Manuel Schneider Date: Wed, 23 Apr 2014 18:10:36 +0200 Subject: Made vnc thread stoppable from outside. Thread kills itself. If the vnc connection cannot be established a timeout kills the thread after a short period of time. --- src/client/vnc/vncthread.cpp | 80 +++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 42 deletions(-) (limited to 'src/client/vnc/vncthread.cpp') diff --git a/src/client/vnc/vncthread.cpp b/src/client/vnc/vncthread.cpp index 86db840..068a88d 100644 --- a/src/client/vnc/vncthread.cpp +++ b/src/client/vnc/vncthread.cpp @@ -45,11 +45,8 @@ VncThread::VncThread(QString host, int port, QString passwd, int quality) : // ALWAYS delete this class from another thread using delete, not deleteLater, or you will deadlock the thread VncThread::~VncThread() { - qDebug("VNC worker destructor called, waiting for thread finishing..."); - _run = false; - while (this->isRunning()) - this->msleep(10); - qDebug("Thread ended."); + qDebug("VNC worker destructor called."); + Q_ASSERT(_run == false); if (_frameBuffer) delete[] _frameBuffer; if (_client != NULL) @@ -118,50 +115,49 @@ void VncThread::run() if (!rfbInitClient(_client, NULL, NULL)) { _client = NULL; // !!! <- if you don't do this you will get a segfault later when you try to clean up _client, as rfbInitClient already did so - this->stop(); - return; } - - qDebug("[%s] Connection successful!", metaObject()->className()); - int one = 1; - setsockopt(_client->sock, SOL_TCP, TCP_NODELAY, &one, sizeof(one)); - one = 1; - setsockopt(_client->sock, SOL_TCP, TCP_QUICKACK, &one, sizeof(one)); - - // Main VNC event loop - emit projectionStarted(); - while (_run) + else { - _connected = true; - const int i = WaitForMessage(_client, 100 * 1000); // wait 100ms for message. returns -1 on error/disconnect, 0 if nothing happened, 1 if new data arrived - if (i < 0) - break; - if (i > 0 && !HandleRFBServerMessage(_client)) - break; - - if (_hasNewLocalSize) + qDebug("[%s] Connection successful!", metaObject()->className()); + int one = 1; + setsockopt(_client->sock, SOL_TCP, TCP_NODELAY, &one, sizeof(one)); + one = 1; + setsockopt(_client->sock, SOL_TCP, TCP_QUICKACK, &one, sizeof(one)); + + // Main VNC event loop + emit projectionStarted(); + } + + if(_client != NULL) + while (_run) { - QMutexLocker lock(&_mutex); - _hasNewLocalSize = false; - _localSize = _newLocalSize; - if (_painter != NULL) - delete _painter; - _imgScaled = QImage(_localSize, QImage::Format_RGB32); - _painter = new QPainter(&_imgScaled); - this->calcScaling(); + _connected = true; + const int i = WaitForMessage(_client, 100 * 1000); // wait 100ms for message. returns -1 on error/disconnect, 0 if nothing happened, 1 if new data arrived + if (i < 0) + break; + if (i > 0 && !HandleRFBServerMessage(_client)) + break; + + if (_hasNewLocalSize) + { + QMutexLocker lock(&_mutex); + _hasNewLocalSize = false; + _localSize = _newLocalSize; + if (_painter != NULL) + delete _painter; + _imgScaled = QImage(_localSize, QImage::Format_RGB32); + _painter = new QPainter(&_imgScaled); + this->calcScaling(); + } } - /* - //work yourself through event queue and fire every event... - while (!_eventQueue.isEmpty()) { - SomeEvent* event = _eventQueue.dequeue(); - event->fire(_client); - delete event; - }*/ - } - _connected = false; + emit projectionStopped(); + while (_run) + this->msleep(100); qDebug("[%s] VNC client stopped.", metaObject()->className()); + this->deleteLater(); + QThread::run(); } const QString VncThread::getDesktopName() const -- cgit v1.2.3-55-g7522