diff --git a/Makefile b/Makefile index 06885e8..7af948d 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,16 @@ -#CC=cc -CFLAGS=-g -Wall -#CFLAGS=-O2 -Wall -RANLIB=ranlib - INCLUDES=-I. VNCSERVERLIB=-L. -lvncserver -L/usr/local/lib -lz -ljpeg -# These two lines enable useage of PThreads -CFLAGS += -DHAVE_PTHREADS -VNCSERVERLIB += -lpthread +# Uncomment these two lines to enable use of PThreads +PTHREADDEF = -DHAVE_PTHREADS +PTHREADLIB = -lpthread + +#CC=cc +CFLAGS=-g -Wall $(PTHREADDEF) +#CFLAGS=-O2 -Wall +RANLIB=ranlib -LIBS=$(LDFLAGS) $(VNCSERVERLIB) +LIBS=$(LDFLAGS) $(VNCSERVERLIB) $(PTHREADLIB) # for Mac OS X OSX_LIBS = -framework ApplicationServices -framework Carbon diff --git a/cursor.c b/cursor.c index 39346b9..c86e377 100644 --- a/cursor.c +++ b/cursor.c @@ -337,19 +337,38 @@ void rfbUndrawCursor(rfbClientPtr cl) rfbCursorPtr c=s->cursor; int j,x1,x2,y1,y2,bpp=s->rfbServerFormat.bitsPerPixel/8, rowstride=s->paddedWidthInBytes; - if(!s->cursorIsDrawn) + +#ifdef HAVE_PTHREADS + pthread_mutex_lock(&c->mutex); +#endif + if(!s->cursorIsDrawn) { +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&c->mutex); +#endif return; + } + /* restore what is under the cursor */ x1=s->cursorX-c->xhot; x2=x1+c->width; if(x1<0) x1=0; if(x2>=s->width) x2=s->width-1; - x2-=x1; if(x2<=0) return; + x2-=x1; if(x2<=0) { +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&c->mutex); +#endif + return; + } y1=s->cursorY-c->yhot; y2=y1+c->height; if(y1<0) y1=0; if(y2>=s->height) y2=s->height-1; - y2-=y1; if(y2<=0) return; + y2-=y1; if(y2<=0) { +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&c->mutex); +#endif + return; + } for(j=0;jframeBuffer+(y1+j)*rowstride+x1*bpp, s->underCursorBuffer+j*x2*bpp, @@ -357,6 +376,9 @@ void rfbUndrawCursor(rfbClientPtr cl) rfbMarkRectAsModified(s,x1,y1,x1+x2,y1+y2); s->cursorIsDrawn = FALSE; +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&c->mutex); +#endif } void rfbDrawCursor(rfbClientPtr cl) @@ -367,10 +389,18 @@ void rfbDrawCursor(rfbClientPtr cl) rowstride=s->paddedWidthInBytes, bufSize,w; if(!c) return; +#ifdef HAVE_PTHREADS + pthread_mutex_lock(&c->mutex); +#endif + if(s->cursorIsDrawn) { + /* is already drawn */ +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&c->mutex); +#endif + return; + } bufSize=c->width*c->height*bpp; w=(c->width+7)/8; - if(s->cursorIsDrawn) - rfbUndrawCursor(cl); if(s->underCursorBufferLenunderCursorBuffer!=NULL) free(s->underCursorBuffer); @@ -383,12 +413,22 @@ void rfbDrawCursor(rfbClientPtr cl) x2=x1+c->width; if(x1<0) { i1=-x1; x1=0; } if(x2>=s->width) x2=s->width-1; - x2-=x1; if(x2<=0) return; /* nothing to do */ + x2-=x1; if(x2<=0) { +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&c->mutex); +#endif + return; /* nothing to do */ + } y1=s->cursorY-c->yhot; y2=y1+c->height; if(y1<0) { j1=-y1; y1=0; } if(y2>=s->height) y2=s->height-1; - y2-=y1; if(y2<=0) return; /* nothing to do */ + y2-=y1; if(y2<=0) { +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&c->mutex); +#endif + return; /* nothing to do */ + } for(j=0;junderCursorBuffer+j*x2*bpp, s->frameBuffer+(y1+j)*rowstride+x1*bpp, @@ -406,6 +446,9 @@ void rfbDrawCursor(rfbClientPtr cl) rfbMarkRectAsModified(s,x1,y1,x1+x2,y1+y2); s->cursorIsDrawn = TRUE; +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&c->mutex); +#endif } /* for debugging */ diff --git a/main.c b/main.c index 54ad19a..d547a8c 100644 --- a/main.c +++ b/main.c @@ -72,10 +72,15 @@ void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion) { rfbClientIteratorPtr iterator; rfbClientPtr cl; + iterator=rfbGetClientIterator(rfbScreen); - while((cl=rfbClientIteratorNext(iterator))) + while((cl=rfbClientIteratorNext(iterator))) { + pthread_mutex_lock(&cl->updateMutex); sraRgnOr(cl->modifiedRegion,modRegion); - + pthread_cond_signal(&cl->updateCond); + pthread_mutex_unlock(&cl->updateMutex); + } + rfbReleaseClientIterator(iterator); } @@ -98,7 +103,7 @@ void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y sraRgnDestroy(region); } -int rfbDeferUpdateTime = 40; /* ms */ +int rfbDeferUpdateTime = 400; /* ms */ #ifdef HAVE_PTHREADS static void * @@ -180,37 +185,14 @@ void* listenerRun(void *data) { rfbScreenInfoPtr rfbScreen=(rfbScreenInfoPtr)data; - int listen_fd, client_fd; - struct sockaddr_in sin, peer; + int client_fd; + struct sockaddr_in peer; pthread_t client_thread; rfbClientPtr cl; - int len, value; - - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = htons(rfbScreen->rfbPort ? rfbScreen->rfbPort : 5901); - - if ((listen_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { - return NULL; - } - value = 1; - if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, - &value, sizeof(value)) < 0) { - rfbLog("setsockopt SO_REUSEADDR failed\n"); - } - - if (bind(listen_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - rfbLog("failed to bind socket\n"); - exit(1); - } - - if (listen(listen_fd, 5) < 0) { - rfbLog("listen failed\n"); - exit(1); - } + int len; len = sizeof(peer); - while ((client_fd = accept(listen_fd, + while ((client_fd = accept(rfbScreen->rfbListenSock, (struct sockaddr *)&peer, &len)) >= 0) { cl = rfbNewClient(rfbScreen,client_fd); diff --git a/rfb.h b/rfb.h index 2864adf..8842de4 100644 --- a/rfb.h +++ b/rfb.h @@ -599,6 +599,9 @@ typedef struct rfbCursor { unsigned short foreRed, foreGreen, foreBlue; /* device-independent color */ unsigned short backRed, backGreen, backBlue; /* device-independent color */ 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 64fa670..2d68e08 100644 --- a/rfbserver.c +++ b/rfbserver.c @@ -260,7 +260,10 @@ rfbClientConnectionGone(cl) rfbClientPtr cl; { int i; + #ifdef HAVE_PTHREADS + pthread_mutex_lock(&cl->updateMutex); + pthread_mutex_lock(&cl->outputMutex); pthread_mutex_lock(&rfbClientListMutex); #endif @@ -289,16 +292,16 @@ rfbClientConnectionGone(cl) if (cl->next) cl->next->prev = cl->prev; -#ifdef HAVE_PTHREADS - pthread_mutex_unlock(&rfbClientListMutex); -#endif - sraRgnDestroy(cl->modifiedRegion); rfbPrintStats(cl); if (cl->translateLookupTable) free(cl->translateLookupTable); +#ifdef HAVE_PTHREADS + pthread_mutex_unlock(&rfbClientListMutex); +#endif + #ifdef HAVE_PTHREADS pthread_cond_destroy(&cl->updateCond); pthread_mutex_destroy(&cl->updateMutex); @@ -839,8 +842,9 @@ rfbSendFramebufferUpdate(cl, updateRegion) if (!cl->screen->cursorIsDrawn && cl->cursorWasChanged) sendCursorShape = TRUE; } else { - if (!cl->screen->cursorIsDrawn) + if (!cl->screen->cursorIsDrawn) { rfbDrawCursor(cl); + } } /* diff --git a/sockets.c b/sockets.c index fe20c49..9721110 100644 --- a/sockets.c +++ b/sockets.c @@ -252,10 +252,14 @@ void rfbCloseClient(cl) rfbClientPtr cl; { + pthread_mutex_lock(&cl->updateMutex); FD_CLR(cl->sock,&(cl->screen->allFds)); - rfbClientConnectionGone(cl); close(cl->sock); cl->sock = -1; + pthread_cond_signal(&cl->updateCond); + pthread_mutex_lock(&cl->updateMutex); + rfbClientConnectionGone(cl); + pthread_mutex_unlock(&cl->updateMutex); }