@@ -461,7 +461,7 @@ clientOutput(void *data)
461461 while (1 ) {
462462 haveUpdate = false;
463463 while (!haveUpdate ) {
464- if (cl -> sock == RFB_INVALID_SOCKET || cl -> state == RFB_SHUTDOWN ) {
464+ if (cl -> sock == RFB_INVALID_SOCKET ) {
465465 /* Client has disconnected. */
466466 return THREAD_ROUTINE_RETURN_VALUE ;
467467 }
@@ -528,7 +528,7 @@ clientInput(void *data)
528528 uintptr_t output_thread = _beginthread (clientOutput , 0 , cl );
529529#endif
530530
531- while (cl -> state != RFB_SHUTDOWN ) {
531+ while (1 ) {
532532 fd_set rfds , wfds , efds ;
533533 struct timeval tv ;
534534 int n ;
@@ -604,10 +604,6 @@ clientInput(void *data)
604604 UNLOCK (cl -> updateMutex );
605605 THREAD_JOIN (output_thread );
606606
607- /* Close client sock */
608- rfbCloseSocket (cl -> sock );
609- cl -> sock = RFB_INVALID_SOCKET ;
610-
611607 rfbClientConnectionGone (cl );
612608
613609 return THREAD_ROUTINE_RETURN_VALUE ;
@@ -624,16 +620,8 @@ listenerRun(void *data)
624620 socklen_t len ;
625621 fd_set listen_fds ; /* temp file descriptor list for select() */
626622
627- /*
628- Only checking socket state here and not using rfbIsActive()
629- because: When rfbShutdownServer() is called by the client, it runs in
630- the client-to-server thread's context, resulting in itself calling
631- its own the pthread_join(), returning immediately, leaving the
632- client-to-server thread to actually terminate _after_ the listener thread
633- is terminated, leaving the client list still populated.
634- */
635623 /* TODO: HTTP is not handled */
636- while (screen -> socketState != RFB_SOCKET_SHUTDOWN ) {
624+ while (rfbIsActive ( screen ) ) {
637625 client_fd = -1 ;
638626 FD_ZERO (& listen_fds );
639627 if (screen -> listenSock != RFB_INVALID_SOCKET )
@@ -1185,14 +1173,22 @@ void rfbShutdownServer(rfbScreenInfoPtr screen,rfbBool disconnectClients) {
11851173 rfbCloseClient (currentCl );
11861174 }
11871175
1176+ #ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
1177+ if (currentCl -> screen -> backgroundLoop ) {
11881178 /*
1189- In threaded mode, rfbClientConnectionGone() is called by the client-to-server thread.
1190- Only need to call this here for non-threaded mode.
1191- */
1192- #if defined(LIBVNCSERVER_HAVE_LIBPTHREAD ) || defined(LIBVNCSERVER_HAVE_WIN32THREADS )
1193- if (!currentCl -> screen -> backgroundLoop )
1179+ Notify the thread. This simply writes a NULL byte to the notify pipe in order to get past the select()
1180+ in clientInput(), the loop in there will then break because the rfbCloseClient() above has set
1181+ currentCl->sock to -1.
1182+ */
1183+ write (currentCl -> pipe_notify_client_thread [1 ], "\x00" , 1 );
1184+ /* And wait for it to finish. */
1185+ pthread_join (currentCl -> client_thread , NULL );
1186+ } else {
1187+ rfbClientConnectionGone (currentCl );
1188+ }
1189+ #else
1190+ rfbClientConnectionGone (currentCl );
11941191#endif
1195- rfbClientConnectionGone (currentCl );
11961192
11971193 currentCl = nextCl ;
11981194 }
@@ -1204,7 +1200,6 @@ void rfbShutdownServer(rfbScreenInfoPtr screen,rfbBool disconnectClients) {
12041200 rfbShutdownSockets (screen );
12051201
12061202#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
1207- screen -> socketState = RFB_SOCKET_SHUTDOWN ; /* Set this so the listener thread ends */
12081203 if (screen -> backgroundLoop ) {
12091204 /*
12101205 Notify the listener thread. This simply writes a NULL byte to the notify pipe in order to get past the select()
0 commit comments