Skip to content

Commit acac779

Browse files
committed
libvncserver: fix HTTPD for multithreaded servers
This changes the select() call in listenerRun() to obey the usec value passed in from rfbRunEventloop(), aligning the multithreaded implementations to the single-threaded one. This in turn allows us to handle incoming HTTP connections as well. Closes #514
1 parent 55be068 commit acac779

2 files changed

Lines changed: 16 additions & 6 deletions

File tree

include/rfb/rfb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,8 @@ typedef struct _rfbScreenInfo
372372
#ifdef LIBVNCSERVER_HAVE_LIBZ
373373
rfbSetXCutTextUTF8ProcPtr setXCutTextUTF8;
374374
#endif
375+
/* Timeout value for select() calls, mainly used for multithreaded servers. */
376+
int select_timeout_usec;
375377
} rfbScreenInfo, *rfbScreenInfoPtr;
376378

377379

src/libvncserver/main.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,7 @@ listenerRun(void *data)
623623
rfbClientPtr cl = NULL;
624624
socklen_t len;
625625
fd_set listen_fds; /* temp file descriptor list for select() */
626+
struct timeval tv;
626627

627628
/*
628629
Only checking socket state here and not using rfbIsActive()
@@ -634,9 +635,9 @@ listenerRun(void *data)
634635
return true, not ending the listener, making the join in rfbShutdownServer()
635636
wait forever...
636637
*/
637-
/* TODO: HTTP is not handled */
638638
while (screen->socketState != RFB_SOCKET_SHUTDOWN) {
639639
client_fd = -1;
640+
cl = NULL;
640641
FD_ZERO(&listen_fds);
641642
if(screen->listenSock != RFB_INVALID_SOCKET)
642643
FD_SET(screen->listenSock, &listen_fds);
@@ -647,7 +648,9 @@ listenerRun(void *data)
647648
screen->maxFd = rfbMax(screen->maxFd, screen->pipe_notify_listener_thread[0]);
648649
#endif
649650

650-
if (select(screen->maxFd+1, &listen_fds, NULL, NULL, NULL) == -1) {
651+
tv.tv_sec = 0;
652+
tv.tv_usec = screen->select_timeout_usec;
653+
if (select(screen->maxFd+1, &listen_fds, NULL, NULL, &tv) == -1) {
651654
rfbLogPerror("listenerRun: error in select");
652655
return THREAD_ROUTINE_RETURN_VALUE;
653656
}
@@ -663,7 +666,7 @@ listenerRun(void *data)
663666
}
664667
#endif
665668

666-
/* there is something on the listening sockets, handle new connections */
669+
/* If there is something on the listening sockets, handle new connections */
667670
len = sizeof (peer);
668671
if (FD_ISSET(screen->listenSock, &listen_fds))
669672
client_fd = accept(screen->listenSock, (struct sockaddr*)&peer, &len);
@@ -674,6 +677,9 @@ listenerRun(void *data)
674677
cl = rfbNewClient(screen,client_fd);
675678
if (cl && !cl->onHold )
676679
rfbStartOnHoldClient(cl);
680+
681+
/* handle HTTP */
682+
rfbHttpCheckFds(screen);
677683
}
678684
return THREAD_ROUTINE_RETURN_VALUE;
679685
}
@@ -1346,6 +1352,11 @@ rfbBool rfbIsActive(rfbScreenInfoPtr screenInfo) {
13461352

13471353
void rfbRunEventLoop(rfbScreenInfoPtr screen, long usec, rfbBool runInBackground)
13481354
{
1355+
if(usec<0)
1356+
usec=screen->deferUpdateTime*1000;
1357+
1358+
screen->select_timeout_usec = usec;
1359+
13491360
if(runInBackground) {
13501361
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
13511362
screen->backgroundLoop = TRUE;
@@ -1368,9 +1379,6 @@ void rfbRunEventLoop(rfbScreenInfoPtr screen, long usec, rfbBool runInBackground
13681379
#endif
13691380
}
13701381

1371-
if(usec<0)
1372-
usec=screen->deferUpdateTime*1000;
1373-
13741382
while(rfbIsActive(screen))
13751383
rfbProcessEvents(screen,usec);
13761384
}

0 commit comments

Comments
 (0)