summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuentin BUATHIER <qbuathier@tetrane.com>2018-08-09 09:33:59 +0200
committerQuentin BUATHIER <qbuathier@tetrane.com>2018-08-09 10:05:37 +0200
commitcedae6e6f97b14f5df3ea7c5f7efd59f2bc9ad82 (patch)
tree253664b8a90865a6d68458156d6bec3c79640b7d
parent96e163bdae65aa2c68e4301cf9ebe29e9f53f3d9 (diff)
downloadlibtdevnc-cedae6e6f97b14f5df3ea7c5f7efd59f2bc9ad82.tar.gz
libtdevnc-cedae6e6f97b14f5df3ea7c5f7efd59f2bc9ad82.zip
Fix the concurrent issue hapenning between the freeing of the client and the clientOutput thread
-rw-r--r--libvncserver/main.c29
-rw-r--r--libvncserver/rfbserver.c5
-rw-r--r--rfb/rfb.h1
3 files changed, 32 insertions, 3 deletions
diff --git a/libvncserver/main.c b/libvncserver/main.c
index 106ebab..c34ae7e 100644
--- a/libvncserver/main.c
+++ b/libvncserver/main.c
@@ -33,6 +33,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
+#include <fcntl.h>
#endif
#include <signal.h>
@@ -533,6 +534,7 @@ clientInput(void *data)
FD_ZERO(&rfds);
FD_SET(cl->sock, &rfds);
+ FD_SET(cl->pipe_notify_client_thread[0], &rfds);
FD_ZERO(&efds);
FD_SET(cl->sock, &efds);
@@ -541,9 +543,13 @@ clientInput(void *data)
if ((cl->fileTransfer.fd!=-1) && (cl->fileTransfer.sending==1))
FD_SET(cl->sock, &wfds);
+ int nfds = cl->pipe_notify_client_thread[0] > cl->sock ? cl->pipe_notify_client_thread[0] : cl->sock;
+
tv.tv_sec = 60; /* 1 minute */
tv.tv_usec = 0;
- n = select(cl->sock + 1, &rfds, &wfds, &efds, &tv);
+
+ n = select(nfds + 1, &rfds, &wfds, &efds, &tv);
+
if (n < 0) {
rfbLogPerror("ReadExact: select");
break;
@@ -558,6 +564,13 @@ clientInput(void *data)
if (FD_ISSET(cl->sock, &wfds))
rfbSendFileTransferChunk(cl);
+ if (FD_ISSET(cl->pipe_notify_client_thread[0], &rfds))
+ {
+ // Reset the pipe
+ char buf;
+ while (read(cl->pipe_notify_client_thread[0], &buf, sizeof(buf)) == sizeof(buf));
+ }
+
if (FD_ISSET(cl->sock, &rfds) || FD_ISSET(cl->sock, &efds))
{
#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
@@ -628,8 +641,12 @@ rfbStartOnHoldClient(rfbClientPtr cl)
{
cl->onHold = FALSE;
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
- if(cl->screen->backgroundLoop)
- pthread_create(&cl->client_thread, NULL, clientInput, (void *)cl);
+ if(cl->screen->backgroundLoop) {
+ pipe(cl->pipe_notify_client_thread);
+ fcntl(cl->pipe_notify_client_thread[0], F_SETFL, O_NONBLOCK);
+
+ pthread_create(&cl->client_thread, NULL, clientInput, (void *)cl);
+ }
#endif
}
@@ -1091,7 +1108,13 @@ void rfbShutdownServer(rfbScreenInfoPtr screen,rfbBool disconnectClients) {
rfbCloseClient(currentCl);
}
+#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
+ // Notify the thread and join it
+ write(currentCl->pipe_notify_client_thread[1], "\x00", 1);
+ pthread_join(currentCl->client_thread, NULL);
+#else
rfbClientConnectionGone(currentCl);
+#endif
currentCl = nextCl;
}
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index 7af6aed..f13050d 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -621,6 +621,11 @@ rfbClientConnectionGone(rfbClientPtr cl)
UNLOCK(cl->sendMutex);
TINI_MUTEX(cl->sendMutex);
+#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
+ close(cl->pipe_notify_client_thread[0]);
+ close(cl->pipe_notify_client_thread[1]);
+#endif
+
rfbPrintStats(cl);
rfbResetStats(cl);
diff --git a/rfb/rfb.h b/rfb/rfb.h
index 3d6d31e..9c60f3d 100644
--- a/rfb/rfb.h
+++ b/rfb/rfb.h
@@ -465,6 +465,7 @@ typedef struct _rfbClientRec {
int protocolMinorVersion;
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
+ int pipe_notify_client_thread[2];
pthread_t client_thread;
#endif