Vine hangs when changing encoding

Hi Vine Community,

I have wrote a small algorithm to automatically change Jpeg compression in Tight to optimize video restitution (reduce Jpeg compression when you play a video).

Here is a demonstration on Windows (TightVNC) : http://www.screentoaster.com/watch/stV0tXQEFMQFpeRVRd

Works nice with UltraVNC, TightVNC, x11vnc… (not with RealVNC, of course, because they don’t support tight.

But it didn’t work with Vine : the server hangs after a few seconds (hangs, don’t crash).

I suspect a lock problem between the threads and I had a look in the code.
An analysis with Apple Instruments shows the following result :
_ thread _pthread_start : waits in listenerRun() - accept()
_ thread _pthread_cond_wait : waits in clientOutput() - semaphore_wait_signal_trap
_ thread _pthread_start waits in : clientInput() -> rfbProcessClientNormalMessage() -> rfbLog() -> NSLogv and so on in the framework
_ thread MainThread waits in refreshCallback() -> semaphore_wait_signal_trap

Looks like the logger blocks and hangs everything. Is it a known issue ?

I will try to add a workaround : add a nolog parameter on the server to avoid logging … Should fix the problem.

Best regards,
Marco FUCCI

Marco, thanks for the find – if you can submit a patch (either here or on SourceForge), I’ll try to make sure it gets put into the latest build.

Hi Jonathan,

I have added a -disableLog parameter and recompiled it. Now it works fine!

It is not a real fix, since I think this is a MacOsX bug, or a protection to avoid that an application flood system logs.

A real fix would be to add a mechanism to avoid to log more than 10 logs per second, for instance … Or to better understand system restrictions on logging.

Here is the patch :

Eclipse Workspace Patch 1.0

#P OSXvnc
Index: OSXvnc-server/main.c

RCS file: /cvsroot/osxvnc/OSXvnc/OSXvnc-server/main.c,v
retrieving revision 1.37
diff -u -r1.37 main.c
— OSXvnc-server/main.c 4 Mar 2008 16:56:30 -0000 1.37
+++ OSXvnc-server/main.c 3 Nov 2008 15:48:21 -0000
@@ -92,6 +92,7 @@
BOOL useIP4 = TRUE;
BOOL unregisterWhenNoConnections = FALSE;
BOOL nonBlocking = FALSE;
+BOOL logEnable = TRUE;

// OSXvnc 0.8 This flag will use a local buffer which will allow us to display the mouse cursor
// Bool rfbLocalBuffer = FALSE;
@@ -134,16 +135,18 @@
*/

void rfbLog(char *format, …) {

  • va_list args;
  • NSString *nsFormat = [[NSString alloc] initWithCString:format];
  • pthread_mutex_lock(&logMutex);
  • va_start(args, format);
  • NSLogv(nsFormat, args);
  • va_end(args);
  • if (!logEnable) {
  •   va_list args;
    
  •   NSString *nsFormat = [[NSString alloc] initWithCString:format];
    
  •   pthread_mutex_lock(&logMutex);
    
  •   va_start(args, format);
    
  •   NSLogv(nsFormat, args);
    
  •   va_end(args);
    
  • [nsFormat release];
  • pthread_mutex_unlock(&logMutex);
  •   [nsFormat release];
    
  •   pthread_mutex_unlock(&logMutex);
    
  • }
    }

void rfbDebugLog(char *format, …) {
@@ -740,7 +743,7 @@
fprintf(stderr, " (default: no, process them)
");
fprintf(stderr, "-disableRichClipboards Don’t share rich clipboard events
");
fprintf(stderr, " (default: no, process them)
");

  • fprintf(stderr, "-connectHost host Host Name or IP of listening client to establishing a reverse conneect
    ");
  • fprintf(stderr, "-connectHost host Host Name or IP of listening client to establishing a reverse connect
    ");
    fprintf(stderr, "-connectPort port TCP port of listening client to establishing a reverse conneect
    ");
    fprintf(stderr, " (default: 5500)
    ");
    fprintf(stderr, "-noupdates Prevent registering for screen updates, for use with x2vnc or win2vnc
    ");
    @@ -750,6 +753,7 @@
    fprintf(stderr, " (default: detect)
    ");
    fprintf(stderr, "-littleEndian Force Little-Endian mode (INTEL)
    ");
    fprintf(stderr, " (default: detect)
    ");

  • fprintf(stderr, "-disableLog Don’t log anything in console
    ");

    /* This isn’t ready to go yet
    {
    @@ -918,6 +922,8 @@
    char *argument = argv[++i];
    restartOnUserSwitch = (argument[0] == ‘y’ || argument[0] == ‘Y’ || argument[0] == ‘t’ || argument[0] == ‘T’ || atoi(argument));
    }

  •   } else if (strcmp(argv[i], "-disableLog") == 0) {
    
  •   	logEnable = FALSE;
      }
    

    }

Best regards,
Marco FUCCI