Commit 130ae151 authored by dscho's avatar dscho

no more compile warnings, pthread final(?) fixes

parent b8c6f3b1
......@@ -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!
......
......@@ -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
......
......@@ -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);
}
......@@ -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 };
......
......@@ -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)
......
......@@ -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*/);
......
......@@ -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);
}
......
......@@ -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;
}
......
......@@ -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
......
......@@ -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"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment