krfb: fix termination and syncing of threads on exit. This resolves issue #2.

Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
pull/10/head
Michele Calgaro 1 year ago
parent 6d6d6edb1d
commit 90abc79efa
Signed by: MicheleC
GPG Key ID: 2A75B7CA8ADED5CF

@ -466,13 +466,13 @@ void rfbMarkRectAsModified(rfbScreenInfoPtr screen,int x1,int y1,int x2,int y2)
#include <unistd.h> #include <unistd.h>
static void * static void *
clientOutput(void *data) clientOutput(ClientOutputHandlerObject::Data d)
{ {
rfbClientPtr cl = (rfbClientPtr)data; rfbClientPtr cl = d.rfbData;
rfbBool haveUpdate; rfbBool haveUpdate;
sraRegion* updateRegion; sraRegion* updateRegion;
while (1) { while (!d.requestExit) {
haveUpdate = false; haveUpdate = false;
while (!haveUpdate) { while (!haveUpdate) {
if (cl->sock == -1) { if (cl->sock == -1) {
@ -532,18 +532,18 @@ clientOutput(void *data)
} }
static void * static void *
clientInput(void *data) clientInput(OnHoldClientHandlerObject::Data d)
{ {
rfbClientPtr cl = (rfbClientPtr)data; rfbClientPtr cl = d.rfbData;
/* Start output thread */ /* Start output thread */
TQEventLoopThread* clientOutputHandlerThread = new TQEventLoopThread(); TQEventLoopThread* clientOutputHandlerThread = new TQEventLoopThread();
ClientOutputHandlerObject* clientOutputHandler = new ClientOutputHandlerObject(); ClientOutputHandlerObject* clientOutputHandler = new ClientOutputHandlerObject();
clientOutputHandler->d = cl; clientOutputHandler->d.rfbData = cl;
clientOutputHandler->moveToThread(clientOutputHandlerThread); clientOutputHandler->moveToThread(clientOutputHandlerThread);
TQTimer::singleShot(0, clientOutputHandler, TQ_SLOT(run())); TQTimer::singleShot(0, clientOutputHandler, TQ_SLOT(run()));
clientOutputHandlerThread->start(); clientOutputHandlerThread->start();
while (1) { while (!d.requestExit) {
fd_set rfds, wfds, efds; fd_set rfds, wfds, efds;
struct timeval tv; struct timeval tv;
int n; int n;
@ -589,7 +589,7 @@ clientInput(void *data)
{ {
/* Reset the pipe */ /* Reset the pipe */
char buf; char buf;
while (read(cl->pipe_notify_client_thread[0], &buf, sizeof(buf)) == sizeof(buf)); while (!d.requestExit && read(cl->pipe_notify_client_thread[0], &buf, sizeof(buf)) == sizeof(buf));
} }
if (FD_ISSET(cl->sock, &rfds) || FD_ISSET(cl->sock, &efds)) if (FD_ISSET(cl->sock, &rfds) || FD_ISSET(cl->sock, &efds))
@ -597,7 +597,7 @@ clientInput(void *data)
#ifdef LIBVNCSERVER_WITH_WEBSOCKETS #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
do { do {
rfbProcessClientMessage(cl); rfbProcessClientMessage(cl);
} while (webSocketsHasDataInBuffer(cl)); } while (!d.requestExit && webSocketsHasDataInBuffer(cl));
#else #else
rfbProcessClientMessage(cl); rfbProcessClientMessage(cl);
#endif #endif
@ -608,6 +608,7 @@ clientInput(void *data)
LOCK(cl->updateMutex); LOCK(cl->updateMutex);
TSIGNAL(cl->updateCond); TSIGNAL(cl->updateCond);
UNLOCK(cl->updateMutex); UNLOCK(cl->updateMutex);
clientOutputHandler->requestExit();
clientOutputHandlerThread->wait(); clientOutputHandlerThread->wait();
delete clientOutputHandlerThread; delete clientOutputHandlerThread;
clientOutputHandlerThread = NULL; clientOutputHandlerThread = NULL;
@ -620,9 +621,9 @@ clientInput(void *data)
} }
static void* static void*
listenerRun(void *data) listenerRun(ControlPipeHandlerObject::Data d)
{ {
rfbScreenInfoPtr screen=(rfbScreenInfoPtr)data; rfbScreenInfoPtr screen=d.rfbData;
int client_fd; int client_fd;
struct sockaddr_storage peer; struct sockaddr_storage peer;
rfbClientPtr cl = NULL; rfbClientPtr cl = NULL;
@ -640,7 +641,7 @@ listenerRun(void *data)
/* TODO: this thread won't die by restarting the server */ /* TODO: this thread won't die by restarting the server */
/* TODO: HTTP is not handled */ /* TODO: HTTP is not handled */
while (1) { while (!d.requestExit) {
client_fd = -1; client_fd = -1;
FD_ZERO(&listen_fds); FD_ZERO(&listen_fds);
if(screen->listenSock >= 0) if(screen->listenSock >= 0)
@ -673,7 +674,7 @@ rfbStartOnHoldClient(rfbClientPtr cl)
{ {
mOnHoldClientHandlerThread = new TQEventLoopThread(); mOnHoldClientHandlerThread = new TQEventLoopThread();
mOnHoldClientHandler = new OnHoldClientHandlerObject(); mOnHoldClientHandler = new OnHoldClientHandlerObject();
mOnHoldClientHandler->d = cl; mOnHoldClientHandler->d.rfbData = cl;
mOnHoldClientHandler->moveToThread(mOnHoldClientHandlerThread); mOnHoldClientHandler->moveToThread(mOnHoldClientHandlerThread);
TQTimer::singleShot(0, mOnHoldClientHandler, TQ_SLOT(run())); TQTimer::singleShot(0, mOnHoldClientHandler, TQ_SLOT(run()));
mOnHoldClientHandlerThread->start(); mOnHoldClientHandlerThread->start();
@ -1097,17 +1098,28 @@ void rfbScreenCleanup(rfbScreenInfoPtr screen)
} }
rfbReleaseClientIterator(i); rfbReleaseClientIterator(i);
if (mOnHoldClientHandler) {
mOnHoldClientHandler->requestExit();
}
if (mOnHoldClientHandlerThread) { if (mOnHoldClientHandlerThread) {
mOnHoldClientHandlerThread->exit(); mOnHoldClientHandlerThread->wait();
delete mOnHoldClientHandlerThread; delete mOnHoldClientHandlerThread;
mOnHoldClientHandlerThread = NULL; mOnHoldClientHandlerThread = NULL;
}
if (mOnHoldClientHandler) {
delete mOnHoldClientHandler; delete mOnHoldClientHandler;
mOnHoldClientHandler = NULL; mOnHoldClientHandler = NULL;
} }
if (mControlPipeHandler) {
mControlPipeHandler->requestExit();
}
if (mControlPipeHandlerThread) { if (mControlPipeHandlerThread) {
mControlPipeHandlerThread->exit(); mControlPipeHandlerThread->wait();
delete mControlPipeHandlerThread; delete mControlPipeHandlerThread;
mControlPipeHandlerThread = NULL; mControlPipeHandlerThread = NULL;
}
if (mControlPipeHandler) {
delete mControlPipeHandler; delete mControlPipeHandler;
mControlPipeHandler = NULL; mControlPipeHandler = NULL;
} }
@ -1305,7 +1317,7 @@ void rfbRunEventLoop(rfbScreenInfoPtr screen, long usec, rfbBool runInBackground
mControlPipeHandlerThread = new TQEventLoopThread(); mControlPipeHandlerThread = new TQEventLoopThread();
mControlPipeHandler = new ControlPipeHandlerObject(); mControlPipeHandler = new ControlPipeHandlerObject();
mControlPipeHandler->d = screen; mControlPipeHandler->d.rfbData = screen;
mControlPipeHandler->moveToThread(mControlPipeHandlerThread); mControlPipeHandler->moveToThread(mControlPipeHandlerThread);
TQTimer::singleShot(0, mControlPipeHandler, TQ_SLOT(run())); TQTimer::singleShot(0, mControlPipeHandler, TQ_SLOT(run()));
mControlPipeHandlerThread->start(); mControlPipeHandlerThread->start();
@ -1324,7 +1336,7 @@ void rfbRunEventLoop(rfbScreenInfoPtr screen, long usec, rfbBool runInBackground
} }
ControlPipeHandlerObject::ControlPipeHandlerObject() : TQObject() { ControlPipeHandlerObject::ControlPipeHandlerObject() : TQObject() {
// d.requestExit = false;
} }
ControlPipeHandlerObject::~ControlPipeHandlerObject() { ControlPipeHandlerObject::~ControlPipeHandlerObject() {
@ -1339,7 +1351,7 @@ void ControlPipeHandlerObject::run(void) {
} }
OnHoldClientHandlerObject::OnHoldClientHandlerObject() : TQObject() { OnHoldClientHandlerObject::OnHoldClientHandlerObject() : TQObject() {
// d.requestExit = false;
} }
OnHoldClientHandlerObject::~OnHoldClientHandlerObject() { OnHoldClientHandlerObject::~OnHoldClientHandlerObject() {
@ -1354,7 +1366,7 @@ void OnHoldClientHandlerObject::run(void) {
} }
ClientOutputHandlerObject::ClientOutputHandlerObject() : TQObject() { ClientOutputHandlerObject::ClientOutputHandlerObject() : TQObject() {
// d.requestExit = false;
} }
ClientOutputHandlerObject::~ClientOutputHandlerObject() { ClientOutputHandlerObject::~ClientOutputHandlerObject() {

@ -21,9 +21,15 @@ class ControlPipeHandlerObject : public TQObject
public slots: public slots:
void run(); void run();
void requestExit() { d.requestExit = true; }
public: public:
rfbScreenInfoPtr d; struct Data
{
rfbScreenInfoPtr rfbData;
bool requestExit;
};
Data d;
}; };
class OnHoldClientHandlerObject : public TQObject class OnHoldClientHandlerObject : public TQObject
@ -36,9 +42,15 @@ class OnHoldClientHandlerObject : public TQObject
public slots: public slots:
void run(); void run();
void requestExit() { d.requestExit = true; }
public: public:
rfbClientPtr d; struct Data
{
rfbClientPtr rfbData;
bool requestExit;
};
Data d;
}; };
class ClientOutputHandlerObject : public TQObject class ClientOutputHandlerObject : public TQObject
@ -51,9 +63,15 @@ class ClientOutputHandlerObject : public TQObject
public slots: public slots:
void run(); void run();
void requestExit() { d.requestExit = true; }
public: public:
rfbClientPtr d; struct Data
{
rfbClientPtr rfbData;
bool requestExit;
};
Data d;
}; };
#endif // _MAIN_H #endif // _MAIN_H

Loading…
Cancel
Save