vnc_view->start();
key_menu = new KeyMenu(this);
}
-
- //QTimer::singleShot(500, this, SLOT(close()));
}
void MainWindow::grabZoomKeys(bool grab)
scroll_area->setWidget(0);
- vnc_view->disconnect(); //remove all signal-slot connections
delete vnc_view;
vnc_view = 0;
disconnect_action->setEnabled(false);
scroll_area->setWidget(0); //remove widget
}
break;
+ default: //avoid compiler warnings
+ break;
}
old_status = status;
VncClientThread *t = (VncClientThread*)rfbClientGetClientData(cl, 0);
Q_ASSERT(t);
- if (t->m_stopped)
- return; //sending data to a stopped thread is not a good idea
-
t->setImage(img);
t->emitUpdated(x, y, w, h);
const bool quitSuccess = wait(1000);
- kDebug(5011) << "~VncClientThread(): Quit VNC thread success:" << quitSuccess;
+ if(!quitSuccess)
+ kDebug(5011) << "~VncClientThread(): Quit failed";
delete [] frameBuffer;
//cl is free()d when event loop exits.
-
- kDebug(5011) << "inMessageHandler: " << inMessageHandler;
-
- kDebug(5011) << "leaving ~VncClientThreod()";
}
void VncClientThread::checkOutputErrorMessage()
void VncClientThread::stop()
{
QMutexLocker locker(&mutex);
-//TODO: not locking the mutex leads to a crash, but at least it stops.
-//TODO: i don't see how this makes a difference
- kDebug(5011) << "stop(): mutex locked";
+
m_stopped = true;
}
locker.unlock();
- inMessageHandler = false;
-
// Main VNC event loop
while (!m_stopped) {
const int i = WaitForMessage(cl, 500);
- if (i < 0)
- break;
- if(m_stopped) {
- kDebug(5011) << "foo2";
+ if(m_stopped or i < 0)
break;
- }
- if (i) {
- inMessageHandler = true;
+
+ if (i)
if (!HandleRFBServerMessage(cl))
break;
- inMessageHandler = false;
- }
-
- if(m_stopped) {
- kDebug(5011) << "foo4";
- break;
- }
locker.relock();
locker.unlock();
}
- kDebug(5011) << "exited main loop";
// Cleanup allocated resources
locker.relock();
- kDebug(5011) << "mutex relocked";
if(!clean)
rfbClientCleanup(cl);
m_stopped = true;
- kDebug(5011) << "exiting run()";
}
ClientEvent::~ClientEvent()
volatile bool m_stopped;
volatile bool m_passwordError;
- bool inMessageHandler;
private slots:
void checkOutputErrorMessage();
m_host = url.host();
m_port = url.port();
+ //BlockingQueuedConnection can cause deadlocks when exiting, handled in startQuitting()
connect(&vncThread, SIGNAL(imageUpdated(int, int, int, int)), this, SLOT(updateImage(int, int, int, int)), Qt::BlockingQueuedConnection);
connect(&vncThread, SIGNAL(gotCut(const QString&)), this, SLOT(setCut(const QString&)), Qt::BlockingQueuedConnection);
connect(&vncThread, SIGNAL(passwordRequest()), this, SLOT(requestPassword()), Qt::BlockingQueuedConnection);
{
kDebug(5011) << "about to quit";
- const bool connected = status() == RemoteView::Connected;
+ //const bool connected = status() == RemoteView::Connected;
setStatus(Disconnecting);
m_quitFlag = true;
- if (connected) {
- kDebug(5011) << "stopping vncThread";
- vncThread.stop();
- }
-
- vncThread.quit();
+ //if(connected) //remove if things work without it
+ vncThread.stop();
const bool quitSuccess = vncThread.wait(700);
-
- kDebug(5011) << "startQuitting(): Quit VNC thread success:" << quitSuccess;
-
+ if(!quitSuccess) {
+ //happens when vncThread wants to call a slot via BlockingQueuedConnection,
+ //needs an event loop in this thread so execution continues after 'emit'
+ QEventLoop loop;
+ if(!loop.processEvents())
+ kDebug(5011) << "BUG: deadlocked, but no events to deliver?";
+ vncThread.wait(700);
+ }
setStatus(Disconnected);
}
if(!QApplication::focusWidget()) { //no focus, we're probably minimized
return;
}
+
//kDebug(5011) << "got update" << width() << height();
/*