summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--TODO25
-rw-r--r--cursor.c73
-rw-r--r--d3des.c2
-rw-r--r--main.c48
-rw-r--r--rfb.h71
-rw-r--r--rfbserver.c171
-rw-r--r--sockets.c59
-rw-r--r--translate.c11
-rw-r--r--vncauth.c1
10 files changed, 227 insertions, 238 deletions
diff --git a/Makefile b/Makefile
index 5fed831..5c92c7a 100644
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,8 @@ INCLUDES=-I.
VNCSERVERLIB=-L. -lvncserver -L/usr/local/lib -lz -ljpeg
# Uncomment these two lines to enable use of PThreads
-#PTHREADDEF = -DHAVE_PTHREADS
-#PTHREADLIB = -lpthread
+PTHREADDEF = -DHAVE_PTHREADS
+PTHREADLIB = -lpthread
# Comment the following line to disable the use of 3 Bytes/Pixel.
# The code for 3 Bytes/Pixel is not very efficient!
diff --git a/TODO b/TODO
index 3790874..904a5fe 100644
--- a/TODO
+++ b/TODO
@@ -2,34 +2,35 @@ immediate:
----------
fix bug in http (java) client with big endian server: byte swapping is broken
-pthreads concept: How to iterate over rfbClientPtr's? So that it can be
- either called from rfbProcessEvents (which locks the list mutex)
- or from the main thread (where the background loop sometimes
- locks the list mutex).
- - cursor drawing!
- - cursor setting!
- - rfbMarkRectAsModified
update to newest TridiaVNC version.
-adapt rdp2vnc (rdesktop)
later:
------
+udp
+documentation
optionally dont draw rich cursors as xcursors
-
-autoconf? at least Sun Solaris compilation
+autoconf? at least Sun Solaris and Windows compilation
perhaps the option (or just hint) not to mark very tiny regions as modified,
because that is inefficient for the encodings.
-udp
rfbConnect, ConnectToTcpAddr
CORBA
-documentation
cursor "smears" sometimes when not using cursor encoding
(seems to be gone now; haven't debugged properly, though)
done:
-----
+.adapt rdp2vnc (rdesktop)
+.pthreads concept: How to iterate over rfbClientPtr's? So that it can be
+ either called from rfbProcessEvents (which locks the list mutex)
+ or from the main thread (where the background loop sometimes
+ locks the list mutex).
+ - cursor drawing!
+ - cursor setting!
+ - rfbMarkRectAsModified
+ (did that by adding a refcount to clients secured by refCountMutex;
+ it also was necessary to check for cl->sock<0 in SendUpdateBuf)
.translate.c: warning about non 8-bit colourmaps
16-bit colourmaps are 192k -> no use without fast net.
.rfbCloseClient
diff --git a/cursor.c b/cursor.c
index 90d6ad9..42afd3f 100644
--- a/cursor.c
+++ b/cursor.c
@@ -225,9 +225,6 @@ rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskSt
char* cp;
unsigned char bit;
-#ifdef HAVE_PTHREADS
- pthread_mutex_init(&cursor->mutex, NULL);
-#endif
cursor->width=width;
cursor->height=height;
//cursor->backRed=cursor->backGreen=cursor->backBlue=0xffff;
@@ -275,9 +272,6 @@ char* rfbMakeMaskForXCursor(int width,int height,char* source)
void rfbFreeCursor(rfbCursorPtr cursor)
{
if(cursor) {
-#ifdef HAVE_PTHREADS
- pthread_mutex_destroy(&cursor->mutex);
-#endif
free(cursor->source);
free(cursor->mask);
free(cursor);
@@ -344,13 +338,9 @@ void rfbUndrawCursor(rfbClientPtr cl)
int j,x1,x2,y1,y2,bpp=s->rfbServerFormat.bitsPerPixel/8,
rowstride=s->paddedWidthInBytes;
-#ifdef HAVE_PTHREADS
- pthread_mutex_lock(&c->mutex);
-#endif
+ LOCK(cl->screen->cursorMutex);
if(!s->cursorIsDrawn) {
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&c->mutex);
-#endif
+ UNLOCK(cl->screen->cursorMutex);
return;
}
@@ -360,9 +350,7 @@ void rfbUndrawCursor(rfbClientPtr cl)
if(x1<0) x1=0;
if(x2>=s->width) x2=s->width-1;
x2-=x1; if(x2<=0) {
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&c->mutex);
-#endif
+ UNLOCK(cl->screen->cursorMutex);
return;
}
y1=s->cursorY-c->yhot;
@@ -370,9 +358,7 @@ void rfbUndrawCursor(rfbClientPtr cl)
if(y1<0) y1=0;
if(y2>=s->height) y2=s->height-1;
y2-=y1; if(y2<=0) {
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&c->mutex);
-#endif
+ UNLOCK(cl->screen->cursorMutex);
return;
}
for(j=0;j<y2;j++)
@@ -382,9 +368,7 @@ void rfbUndrawCursor(rfbClientPtr cl)
rfbMarkRectAsModified(s,x1,y1,x1+x2,y1+y2);
s->cursorIsDrawn = FALSE;
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&c->mutex);
-#endif
+ UNLOCK(cl->screen->cursorMutex);
}
void rfbDrawCursor(rfbClientPtr cl)
@@ -395,14 +379,10 @@ void rfbDrawCursor(rfbClientPtr cl)
rowstride=s->paddedWidthInBytes,
bufSize,w;
if(!c) return;
-#ifdef HAVE_PTHREADS
- pthread_mutex_lock(&c->mutex);
-#endif
+ LOCK(cl->screen->cursorMutex);
if(s->cursorIsDrawn) {
/* is already drawn */
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&c->mutex);
-#endif
+ UNLOCK(cl->screen->cursorMutex);
return;
}
bufSize=c->width*c->height*bpp;
@@ -420,9 +400,7 @@ void rfbDrawCursor(rfbClientPtr cl)
if(x1<0) { i1=-x1; x1=0; }
if(x2>=s->width) x2=s->width-1;
x2-=x1; if(x2<=0) {
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&c->mutex);
-#endif
+ UNLOCK(cl->screen->cursorMutex);
return; /* nothing to do */
}
y1=s->cursorY-c->yhot;
@@ -430,9 +408,7 @@ void rfbDrawCursor(rfbClientPtr cl)
if(y1<0) { j1=-y1; y1=0; }
if(y2>=s->height) y2=s->height-1;
y2-=y1; if(y2<=0) {
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&c->mutex);
-#endif
+ UNLOCK(cl->screen->cursorMutex);
return; /* nothing to do */
}
for(j=0;j<y2;j++)
@@ -452,9 +428,7 @@ void rfbDrawCursor(rfbClientPtr cl)
rfbMarkRectAsModified(s,x1,y1,x1+x2,y1+y2);
s->cursorIsDrawn = TRUE;
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&c->mutex);
-#endif
+ UNLOCK(cl->screen->cursorMutex);
}
/* for debugging */
@@ -475,26 +449,21 @@ void rfbPrintXCursor(rfbCursorPtr cursor)
extern void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c,Bool freeOld)
{
+ rfbClientIteratorPtr i = rfbGetClientIterator(rfbScreen);
rfbClientPtr cl;
-#ifdef HAVE_PTHREADS
- pthread_mutex_lock(rfbScreen->cursor->mutex);
-#endif
- for(cl=rfbScreen->rfbClientHead;cl;cl=cl->next)
- if(cl->sock>=0) {
-#ifdef HAVE_PTHREADS
- pthread_mutex_lock(cl->updateMutex);
-#endif
- rfbUndrawCursor(cl);
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(cl->updateMutex);
-#endif
+
+ LOCK(rfbScreen->cursorMutex);
+
+ while((cl=rfbClientIteratorNext(i))) {
+ LOCK(cl->updateMutex);
+ rfbUndrawCursor(cl);
+ UNLOCK(cl->updateMutex);
}
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(rfbScreen->cursor->mutex);
-#endif
-
+
if(freeOld && rfbScreen->cursor)
rfbFreeCursor(rfbScreen->cursor);
rfbScreen->cursor = c;
+
+ UNLOCK(rfbScreen->cursorMutex);
}
diff --git a/d3des.c b/d3des.c
index 8a358ce..60e6473 100644
--- a/d3des.c
+++ b/d3des.c
@@ -34,12 +34,14 @@ static void desfunc(unsigned long *, unsigned long *);
static void cookey(unsigned long *);
static unsigned long KnL[32] = { 0L };
+/*
static unsigned long KnR[32] = { 0L };
static unsigned long Kn3[32] = { 0L };
static unsigned char Df_Key[24] = {
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 };
+*/
static unsigned short bytebit[8] = {
01, 02, 04, 010, 020, 040, 0100, 0200 };
diff --git a/main.c b/main.c
index b709bb7..7412b30 100644
--- a/main.c
+++ b/main.c
@@ -75,14 +75,10 @@ void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion)
iterator=rfbGetClientIterator(rfbScreen);
while((cl=rfbClientIteratorNext(iterator))) {
-#ifdef HAVE_PTHREADS
- pthread_mutex_lock(&cl->updateMutex);
-#endif
+ LOCK(cl->updateMutex);
sraRgnOr(cl->modifiedRegion,modRegion);
-#ifdef HAVE_PTHREADS
- pthread_cond_signal(&cl->updateCond);
- pthread_mutex_unlock(&cl->updateMutex);
-#endif
+ SIGNAL(cl->updateCond);
+ UNLOCK(cl->updateMutex);
}
rfbReleaseClientIterator(iterator);
@@ -120,11 +116,11 @@ clientOutput(void *data)
while (1) {
haveUpdate = false;
- pthread_mutex_lock(&cl->updateMutex);
+ LOCK(cl->updateMutex);
while (!haveUpdate) {
if (cl->sock == -1) {
/* Client has disconnected. */
- pthread_mutex_unlock(&cl->updateMutex);
+ UNLOCK(cl->updateMutex);
return NULL;
}
updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
@@ -132,24 +128,24 @@ clientOutput(void *data)
sraRgnDestroy(updateRegion);
if (!haveUpdate) {
- pthread_cond_wait(&cl->updateCond, &cl->updateMutex);
+ WAIT(cl->updateCond, cl->updateMutex);
}
}
/* OK, now, to save bandwidth, wait a little while for more
updates to come along. */
- pthread_mutex_unlock(&cl->updateMutex);
+ UNLOCK(cl->updateMutex);
usleep(rfbDeferUpdateTime * 1000);
/* Now, get the region we're going to update, and remove
it from cl->modifiedRegion _before_ we send the update.
That way, if anything that overlaps the region we're sending
is updated, we'll be sure to do another update later. */
- pthread_mutex_lock(&cl->updateMutex);
+ LOCK(cl->updateMutex);
updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
sraRgnAnd(updateRegion,cl->requestedRegion);
sraRgnSubtract(cl->modifiedRegion,updateRegion);
- pthread_mutex_unlock(&cl->updateMutex);
+ UNLOCK(cl->updateMutex);
/* Now actually send the update. */
rfbSendFramebufferUpdate(cl, updateRegion);
@@ -176,10 +172,10 @@ clientInput(void *data)
}
/* Get rid of the output thread. */
- pthread_mutex_lock(&cl->updateMutex);
- pthread_cond_signal(&cl->updateCond);
- pthread_mutex_unlock(&cl->updateMutex);
- pthread_join(output_thread, NULL);
+ LOCK(cl->updateMutex);
+ SIGNAL(cl->updateCond);
+ UNLOCK(cl->updateMutex);
+ IF_PTHREADS(pthread_join(output_thread, NULL));
rfbClientConnectionGone(cl);
@@ -389,6 +385,7 @@ rfbScreenInfoPtr rfbGetScreen(int argc,char** argv,
rfbScreen->dontSendFramebufferUpdate = FALSE;
rfbScreen->cursorX=rfbScreen->cursorY=rfbScreen->underCursorBufferLen=0;
rfbScreen->underCursorBuffer=NULL;
+ //INIT_MUTEX(rfbScreen->cursorMutex);
/* proc's and hook's */
@@ -410,6 +407,11 @@ rfbScreenInfoPtr rfbGetScreen(int argc,char** argv,
void rfbScreenCleanup(rfbScreenInfoPtr rfbScreen)
{
/* TODO */
+ if(rfbScreen->frameBuffer)
+ free(rfbScreen->frameBuffer);
+ if(rfbScreen->colourMap.data.bytes)
+ free(rfbScreen->colourMap.data.bytes);
+ TINI_MUTEX(rfbScreen->cursorMutex);
free(rfbScreen);
}
@@ -422,7 +424,8 @@ void rfbInitServer(rfbScreenInfoPtr rfbScreen)
void
rfbProcessEvents(rfbScreenInfoPtr rfbScreen,long usec)
{
- rfbClientPtr cl,cl_next;
+ rfbClientIteratorPtr i;
+ rfbClientPtr cl;
rfbCheckFds(rfbScreen,usec);
httpCheckFds(rfbScreen);
@@ -430,17 +433,14 @@ rfbProcessEvents(rfbScreenInfoPtr rfbScreen,long usec)
corbaCheckFds(rfbScreen);
#endif
- /* this needn't be thread safe:
- you use rfbRunEventLoop(..,TRUE) for pthreads. */
- cl=rfbScreen->rfbClientHead;
- while(cl) {
- cl_next=cl->next;
+ i = rfbGetClientIterator(rfbScreen);
+ while((cl=rfbClientIteratorNext(i))) {
if(cl->sock>=0 && FB_UPDATE_PENDING(cl))
rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
if(cl->sock==-1)
rfbClientConnectionGone(cl);
- cl=cl_next;
}
+ rfbReleaseClientIterator(i);
}
void rfbRunEventLoop(rfbScreenInfoPtr rfbScreen, long usec, Bool runInBackground)
diff --git a/rfb.h b/rfb.h
index 81a165c..efb69d2 100644
--- a/rfb.h
+++ b/rfb.h
@@ -52,15 +52,6 @@ int max(int,int);
#include <rfbproto.h>
-#ifdef HAVE_PTHREADS
-#include <pthread.h>
-#define IF_PTHREADS(x) (x)
-#else
-#define IF_PTHREADS(x)
-#endif
-
-
-
#ifdef __linux__
#include <endian.h>
#else
@@ -84,6 +75,47 @@ int max(int,int);
#include <netinet/in.h>
+#ifdef HAVE_PTHREADS
+#include <pthread.h>
+#if 0
+#define LOCK(mutex) fprintf(stderr,"%s:%d LOCK(%s)\n",__FILE__,__LINE__,#mutex)
+#define UNLOCK(mutex) fprintf(stderr,"%s:%d UNLOCK(%s)\n",__FILE__,__LINE__,#mutex)
+#define MUTEX(mutex)
+#define INIT_MUTEX(mutex) fprintf(stderr,"%s:%d INIT_MUTEX(%s)\n",__FILE__,__LINE__,#mutex)
+#define TINI_MUTEX(mutex) fprintf(stderr,"%s:%d TINI_MUTEX(%s)\n",__FILE__,__LINE__,#mutex)
+#define SIGNAL(cond) fprintf(stderr,"%s:%d SIGNAL(%s)\n",__FILE__,__LINE__,#cond)
+#define WAIT(cond,mutex) fprintf(stderr,"%s:%d WAIT(%s,%s)\n",__FILE__,__LINE__,#cond,#mutex)
+#define COND(cond)
+#define INIT_COND(cond) fprintf(stderr,"%s:%d INIT_COND(%s)\n",__FILE__,__LINE__,#cond)
+#define TINI_COND(cond) fprintf(stderr,"%s:%d TINI_COND(%s)\n",__FILE__,__LINE__,#cond)
+#define IF_PTHREAD(x)
+#else
+#define LOCK(mutex) pthread_mutex_lock(&(mutex))
+#define UNLOCK(mutex) pthread_mutex_unlock(&(mutex))
+#define MUTEX(mutex) pthread_mutex_t (mutex)
+#define INIT_MUTEX(mutex) pthread_mutex_init(&(mutex),NULL)
+#define TINI_MUTEX(mutex) pthread_mutex_destroy(&(mutex))
+#define SIGNAL(cond) pthread_cond_signal(&(cond))
+#define WAIT(cond,mutex) pthread_cond_wait(&(cond),&(mutex))
+#define COND(cond) pthread_cond_t (cond)
+#define INIT_COND(cond) pthread_cond_init(&(cond),NULL)
+#define TINI_COND(cond) pthread_cond_destroy(&(cond))
+#define IF_PTHREADS(x) x
+#endif
+#else
+#define LOCK(mutex)
+#define UNLOCK(mutex)
+#define MUTEX(mutex)
+#define INIT_MUTEX(mutex)
+#define TINI_MUTEX(mutex)
+#define SIGNAL(cond) this_is_unsupported
+#define WAIT(cond,mutex) this_is_unsupported
+#define COND(cond)
+#define INIT_COND(cond)
+#define TINI_COND(cond)
+#define IF_PTHREADS(x)
+#endif
+
#define MAX_ENCODINGS 10
struct rfbClientRec;
@@ -210,6 +242,7 @@ typedef struct
Bool rfbDontDisconnect;
struct rfbClientRec* rfbClientHead;
struct rfbCursor* cursor;
+ MUTEX(cursorMutex);
/* the following members have to be supplied by the serving process */
char* frameBuffer;
@@ -273,7 +306,7 @@ typedef struct rfbClientRec {
*/
void* clientData;
ClientGoneHookPtr clientGoneHook;
-
+
int sock;
char *host;
/* Possible client states: */
@@ -324,10 +357,17 @@ typedef struct rfbClientRec {
#ifdef HAVE_PTHREADS
- pthread_mutex_t dontKillMutex; /* if you need a reliable clientPtr */
- pthread_mutex_t outputMutex;
- pthread_mutex_t updateMutex;
- pthread_cond_t updateCond;
+ /* whenever a client is referenced, the refCount has to be incremented
+ and afterwards decremented.
+ Use the functions rfbIncrClientRef(cl) and rfbDecrClientRef(cl);
+ */
+ int refCount;
+ MUTEX(refCountMutex);
+ COND(deleteCond);
+
+ MUTEX(outputMutex);
+ MUTEX(updateMutex);
+ COND(updateCond);
#endif
sraRegionPtr modifiedRegion;
@@ -598,9 +638,6 @@ typedef struct rfbCursor {
unsigned short foreRed, foreGreen, foreBlue; /* device-independent colour */
unsigned short backRed, backGreen, backBlue; /* device-independent colour */
unsigned char *richSource; /* source bytes for a rich cursor */
-#ifdef HAVE_PTHREADS
- pthread_mutex_t mutex;
-#endif
} rfbCursor, *rfbCursorPtr;
extern Bool rfbSendCursorShape(rfbClientPtr cl/*, rfbScreenInfoPtr pScreen*/);
diff --git a/rfbserver.c b/rfbserver.c
index c1bf69d..930a9ed 100644
--- a/rfbserver.c
+++ b/rfbserver.c
@@ -33,9 +33,6 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
-#ifdef HAVE_PTHREADS
-#include <pthread.h>
-#endif
rfbClientPtr pointerClient = NULL; /* Mutex for pointer events */
@@ -43,52 +40,74 @@ static void rfbProcessClientProtocolVersion(rfbClientPtr cl);
static void rfbProcessClientNormalMessage(rfbClientPtr cl);
static void rfbProcessClientInitMessage(rfbClientPtr cl);
+#ifdef HAVE_PTHREADS
+void rfbIncrClientRef(rfbClientPtr cl)
+{
+ LOCK(cl->refCountMutex);
+ cl->refCount++;
+ UNLOCK(cl->refCountMutex);
+}
+
+void rfbDecrClientRef(rfbClientPtr cl)
+{
+ LOCK(cl->refCountMutex);
+ cl->refCount--;
+ if(cl->refCount<=0) /* just to be sure also < 0 */
+ SIGNAL(cl->deleteCond);
+ UNLOCK(cl->refCountMutex);
+}
+#endif
+
+MUTEX(rfbClientListMutex);
struct rfbClientIterator {
- rfbClientPtr next;
+ rfbClientPtr next;
+ rfbScreenInfoPtr screen;
};
-#ifdef HAVE_PTHREADS
-static pthread_mutex_t rfbClientListMutex;
-#endif
-static struct rfbClientIterator rfbClientIteratorInstance;
-
void
rfbClientListInit(rfbScreenInfoPtr rfbScreen)
{
rfbScreen->rfbClientHead = NULL;
-#ifdef HAVE_PTHREADS
- pthread_mutex_init(&rfbClientListMutex, NULL);
-#endif
}
rfbClientIteratorPtr
rfbGetClientIterator(rfbScreenInfoPtr rfbScreen)
{
-#ifdef HAVE_PTHREADS
- pthread_mutex_lock(&rfbClientListMutex);
-#endif
- rfbClientIteratorInstance.next = rfbScreen->rfbClientHead;
-
- return &rfbClientIteratorInstance;
+ rfbClientIteratorPtr i =
+ (rfbClientIteratorPtr)malloc(sizeof(struct rfbClientIterator));
+ i->next = 0;
+ i->screen = rfbScreen;
+ return i;
}
rfbClientPtr
-rfbClientIteratorNext(rfbClientIteratorPtr iterator)
+rfbClientIteratorNext(rfbClientIteratorPtr i)
{
- rfbClientPtr result;
- result = iterator->next;
- if (result)
- iterator->next = result->next;
- return result;
+ if(i->next == 0) {
+ LOCK(rfbClientListMutex);
+ i->next = i->screen->rfbClientHead;
+ UNLOCK(rfbClientListMutex);
+ } else {
+ IF_PTHREADS(rfbClientPtr cl = i->next);
+ i->next = i->next->next;
+ IF_PTHREADS(rfbDecrClientRef(cl));
+ }
+
+#ifdef HAVE_PTHREADS
+ while(i->next && i->next->sock<0)
+ i->next = i->next->next;
+ if(i->next)
+ rfbIncrClientRef(i->next);
+#endif
+
+ return i->next;
}
void
rfbReleaseClientIterator(rfbClientIteratorPtr iterator)
{
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&rfbClientListMutex);
-#endif
+ IF_PTHREADS(if(iterator->next) rfbDecrClientRef(iterator->next));
}
@@ -169,9 +188,7 @@ rfbNewClient(rfbScreen,sock)
getpeername(sock, (struct sockaddr *)&addr, &addrlen);
cl->host = strdup(inet_ntoa(addr.sin_addr));
-#ifdef HAVE_PTHREADS
- pthread_mutex_init(&cl->outputMutex, NULL);
-#endif
+ INIT_MUTEX(cl->outputMutex);
cl->state = RFB_PROTOCOL_VERSION;
@@ -189,10 +206,8 @@ rfbNewClient(rfbScreen,sock)
cl->modifiedRegion =
sraRgnCreateRect(0,0,rfbScreen->width,rfbScreen->height);
-#ifdef HAVE_PTHREADS
- pthread_mutex_init(&cl->updateMutex, NULL);
- pthread_cond_init(&cl->updateCond, NULL);
-#endif
+ INIT_MUTEX(cl->updateMutex);
+ INIT_COND(cl->updateCond);
cl->requestedRegion = sraRgnCreate();
@@ -200,18 +215,16 @@ rfbNewClient(rfbScreen,sock)
cl->translateFn = rfbTranslateNone;
cl->translateLookupTable = NULL;
-#ifdef HAVE_PTHREADS
- pthread_mutex_lock(&rfbClientListMutex);
-#endif
+ LOCK(rfbClientListMutex);
+
+ cl->refCount = 0;
cl->next = rfbScreen->rfbClientHead;
cl->prev = NULL;
if (rfbScreen->rfbClientHead)
rfbScreen->rfbClientHead->prev = cl;
rfbScreen->rfbClientHead = cl;
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&rfbClientListMutex);
-#endif
+ UNLOCK(rfbClientListMutex);
cl->tightCompressLevel = TIGHT_DEFAULT_COMPRESSION;
cl->tightQualityLevel = -1;
@@ -261,12 +274,23 @@ rfbClientConnectionGone(cl)
{
int i;
+ LOCK(rfbClientListMutex);
+
+ if (cl->prev)
+ cl->prev->next = cl->next;
+ else
+ cl->screen->rfbClientHead = cl->next;
+ if (cl->next)
+ cl->next->prev = cl->prev;
+
#ifdef HAVE_PTHREADS
- /*
- pthread_mutex_lock(&cl->updateMutex);
- pthread_mutex_lock(&cl->outputMutex);
- */
- pthread_mutex_lock(&rfbClientListMutex);
+ LOCK(cl->refCountMutex);
+ if(cl->refCount) {
+ UNLOCK(cl->refCountMutex);
+ WAIT(cl->deleteCond,cl->refCountMutex);
+ } else {
+ UNLOCK(cl->refCountMutex);
+ }
#endif
cl->clientGoneHook(cl);
@@ -287,28 +311,19 @@ rfbClientConnectionGone(cl)
if (pointerClient == cl)
pointerClient = NULL;
- if (cl->prev)
- cl->prev->next = cl->next;
- else
- cl->screen->rfbClientHead = cl->next;
- if (cl->next)
- cl->next->prev = cl->prev;
-
sraRgnDestroy(cl->modifiedRegion);
- rfbPrintStats(cl);
+ UNLOCK(rfbClientListMutex);
if (cl->translateLookupTable) free(cl->translateLookupTable);
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&rfbClientListMutex);
-#endif
+ TINI_COND(cl->updateCond);
+ TINI_MUTEX(cl->updateMutex);
-#ifdef HAVE_PTHREADS
- pthread_cond_destroy(&cl->updateCond);
- pthread_mutex_destroy(&cl->updateMutex);
- pthread_mutex_destroy(&cl->outputMutex);
-#endif
+ LOCK(cl->outputMutex);
+ TINI_MUTEX(cl->outputMutex);
+
+ rfbPrintStats(cl);
xfree(cl);
}
@@ -694,9 +709,7 @@ rfbProcessClientNormalMessage(cl)
Swap16IfLE(msg.fur.x)+Swap16IfLE(msg.fur.w),
Swap16IfLE(msg.fur.y)+Swap16IfLE(msg.fur.h));
-#ifdef HAVE_PTHREADS
- pthread_mutex_lock(&cl->updateMutex);
-#endif
+ LOCK(cl->updateMutex);
sraRgnOr(cl->requestedRegion,tmpRegion);
if (!cl->readyForSetColourMapEntries) {
@@ -713,19 +726,16 @@ rfbProcessClientNormalMessage(cl)
if (!msg.fur.incremental) {
sraRgnOr(cl->modifiedRegion,tmpRegion);
sraRgnSubtract(cl->copyRegion,tmpRegion);
- }
-#ifdef HAVE_PTHREADS
- pthread_cond_signal(&cl->updateCond);
- pthread_mutex_unlock(&cl->updateMutex);
-#endif
-
- if(cl->sock>=0 && FB_UPDATE_PENDING(cl)) {
- rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
- }
+ }
+ SIGNAL(cl->updateCond);
+ UNLOCK(cl->updateMutex);
- sraRgnDestroy(tmpRegion);
+ if(cl->sock>=0 && FB_UPDATE_PENDING(cl)) {
+ rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
+ }
+ sraRgnDestroy(tmpRegion);
- return;
+ return;
}
case rfbKeyEvent:
@@ -1209,6 +1219,9 @@ Bool
rfbSendUpdateBuf(cl)
rfbClientPtr cl;
{
+ if(cl->sock<0)
+ return FALSE;
+
if (WriteExact(cl, cl->updateBuf, cl->ublen) < 0) {
rfbLogPerror("rfbSendUpdateBuf: write");
rfbCloseClient(cl);
@@ -1275,17 +1288,19 @@ rfbSendSetColourMapEntries(cl, firstColour, nColours)
void
rfbSendBell(rfbScreenInfoPtr rfbScreen)
{
- rfbClientPtr cl, nextCl;
+ rfbClientIteratorPtr i;
+ rfbClientPtr cl;
rfbBellMsg b;
- for (cl = rfbScreen->rfbClientHead; cl; cl = nextCl) {
- nextCl = cl->next;
+ i = rfbGetClientIterator(rfbScreen);
+ while((cl=rfbClientIteratorNext(i))) {
b.type = rfbBell;
if (WriteExact(cl, (char *)&b, sz_rfbBellMsg) < 0) {
rfbLogPerror("rfbSendBell: write");
rfbCloseClient(cl);
}
}
+ rfbReleaseClientIterator(i);
}
diff --git a/sockets.c b/sockets.c
index da5d99f..ef83269 100644
--- a/sockets.c
+++ b/sockets.c
@@ -142,7 +142,7 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
const int one = 1;
int sock;
rfbClientIteratorPtr i;
- rfbClientPtr cl,cl_next;
+ rfbClientPtr cl;
if (!rfbScreen->inetdInitDone && rfbScreen->inetdSock != -1) {
rfbNewClientConnection(rfbScreen,rfbScreen->inetdSock);
@@ -233,34 +233,12 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
return;
}
- /* I know that this is horrible. But we have the following problem:
- inside this loop, the IO functions access the clients via the
- iterator.
- So we have to lock rfbClientListMutex to fetch a reliable
- rfbClientHead. Remember, a client can just go away in a multithreaded
- environment. So we have to lock the next client before working with
- the current.
- */
i = rfbGetClientIterator(rfbScreen);
- cl = rfbClientIteratorNext(i);
- if(cl) {
-#ifdef HAVE_PTHREADS
- //pthread_mutex_lock(&cl->updateMutex);
-#endif
- }
- rfbReleaseClientIterator(i);
-
- while(cl) {
- cl_next = cl->next;
-#ifdef HAVE_PTHREADS
- //pthread_mutex_unlock(&cl->updateMutex);
- //if(cl_next)
- //pthread_mutex_lock(&cl_next->updateMutex);
-#endif
+ while((cl = rfbClientIteratorNext(i))) {
if (FD_ISSET(cl->sock, &fds) && FD_ISSET(cl->sock, &(rfbScreen->allFds)))
rfbProcessClientMessage(cl);
- cl=cl_next;
}
+ rfbReleaseClientIterator(i);
}
@@ -276,17 +254,12 @@ void
rfbCloseClient(cl)
rfbClientPtr cl;
{
-#ifdef HAVE_PTHREADS
- pthread_mutex_lock(&cl->updateMutex);
-#endif
+ LOCK(cl->updateMutex);
FD_CLR(cl->sock,&(cl->screen->allFds));
close(cl->sock);
cl->sock = -1;
-#ifdef HAVE_PTHREADS
- pthread_cond_signal(&cl->updateCond);
- //pthread_mutex_lock(&cl->updateMutex);
- pthread_mutex_unlock(&cl->updateMutex);
-#endif
+ SIGNAL(cl->updateCond);
+ UNLOCK(cl->updateMutex);
}
@@ -362,9 +335,7 @@ WriteExact(cl, buf, len)
struct timeval tv;
int totalTimeWaited = 0;
-#ifdef HAVE_PTHREADS
- pthread_mutex_lock(&cl->outputMutex);
-#endif
+ LOCK(cl->outputMutex);
while (len > 0) {
n = write(sock, buf, len);
@@ -380,9 +351,7 @@ WriteExact(cl, buf, len)
} else {
if (errno != EWOULDBLOCK && errno != EAGAIN) {
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&cl->outputMutex);
-#endif
+ UNLOCK(cl->outputMutex);
return n;
}
@@ -397,18 +366,14 @@ WriteExact(cl, buf, len)
n = select(sock+1, NULL, &fds, NULL, &tv);
if (n < 0) {
rfbLogPerror("WriteExact: select");
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&cl->outputMutex);
-#endif
+ UNLOCK(cl->outputMutex);
return n;
}
if (n == 0) {
totalTimeWaited += 5000;
if (totalTimeWaited >= rfbMaxClientWait) {
errno = ETIMEDOUT;
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&cl->outputMutex);
-#endif
+ UNLOCK(cl->outputMutex);
return -1;
}
} else {
@@ -416,9 +381,7 @@ WriteExact(cl, buf, len)
}
}
}
-#ifdef HAVE_PTHREADS
- pthread_mutex_unlock(&cl->outputMutex);
-#endif
+ UNLOCK(cl->outputMutex);
return 1;
}
diff --git a/translate.c b/translate.c
index 59128a5..5efc52c 100644
--- a/translate.c
+++ b/translate.c
@@ -449,12 +449,13 @@ rfbSetClientColourMaps(rfbScreen, firstColour, nColours)
int firstColour;
int nColours;
{
- rfbClientPtr cl, nextCl;
+ rfbClientIteratorPtr i;
+ rfbClientPtr cl;
- for (cl = rfbScreen->rfbClientHead; cl; cl = nextCl) {
- nextCl = cl->next;
- rfbSetClientColourMap(cl, firstColour, nColours);
- }
+ i = rfbGetClientIterator(rfbScreen);
+ while((cl = rfbClientIteratorNext(i)))
+ rfbSetClientColourMap(cl, firstColour, nColours);
+ rfbReleaseClientIterator(i);
}
static void
diff --git a/vncauth.c b/vncauth.c
index 69f38cf..75f1cc3 100644
--- a/vncauth.c
+++ b/vncauth.c
@@ -26,6 +26,7 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/time.h>
#include "rfb.h"
#include "d3des.h"