Both clientInput() and rfbScreenCleanup() call
rfbClientConnectionGone(). This works only if clientInput() wins the
race with a sufficient margin to take the client off the list before
rfbScreenCleanup() sees it. Otherwise, rfbClientConnectionGone() is
called twice, with potentially disastrous results.
diff -rup xen-3.1.0-src/LibVNCServer-0.8.2/libvncserver/main.c xen-3.1.0-hacked/LibVNCServer-0.8.2/libvncserver/main.c
--- xen-3.1.0-src/LibVNCServer-0.8.2/libvncserver/main.c 2007-07-30 14:41:46.000000000 +0200
+++ xen-3.1.0-hacked/LibVNCServer-0.8.2/libvncserver/main.c 2007-07-31 15:52:51.000000000 +0200
@@ -494,6 +494,8 @@ clientInput(void *data)
pthread_t output_thread;
pthread_create(&output_thread, NULL, clientOutput, (void *)cl);
+ rfbIncrClientRef(cl);
+
while (1) {
fd_set rfds, wfds, efds;
struct timeval tv;
@@ -555,7 +557,7 @@ clientInput(void *data)
UNLOCK(cl->updateMutex);
IF_PTHREADS(pthread_join(output_thread, NULL));
- rfbClientConnectionGone(cl);
+ rfbDecrClientRef(cl);
return NULL;
}