From ba47e60eeb3588ce04d91eb618934b0076db13ee Mon Sep 17 00:00:00 2001 From: Corey Johnson & Kevin Sawicki Date: Tue, 26 Feb 2013 08:58:52 -0800 Subject: [PATCH] Synchronize reads of task's stdout/stderr This ensures that all the available data on standard out and standard error has been read before the terminate handler calls the JavaScript callback. Without this synchronization the command panel specs occasionally fail. --- native/v8_extensions/native.mm | 54 +++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/native/v8_extensions/native.mm b/native/v8_extensions/native.mm index 9ce163a30..6af7622fa 100644 --- a/native/v8_extensions/native.mm +++ b/native/v8_extensions/native.mm @@ -447,41 +447,49 @@ namespace v8_extensions { context->Exit(); - stdout.fileHandleForReading.writeabilityHandler = nil; - stderr.fileHandleForReading.writeabilityHandler = nil; + stdout.fileHandleForReading.readabilityHandler = nil; + stderr.fileHandleForReading.readabilityHandler = nil; }; task.terminationHandler = ^(NSTask *) { - NSString *output = [[NSString alloc] initWithData:[[stdout fileHandleForReading] readDataToEndOfFile] encoding:NSUTF8StringEncoding]; - NSString *errorOutput = [[NSString alloc] initWithData:[[stderr fileHandleForReading] readDataToEndOfFile] encoding:NSUTF8StringEncoding]; - dispatch_sync(dispatch_get_main_queue(), ^() { - taskTerminatedHandle(output, errorOutput); - }); - [output release]; - [errorOutput release]; + @synchronized(task) { + NSData *outputData = [[stdout fileHandleForReading] readDataToEndOfFile]; + NSString *output = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding]; + NSData *errorData = [[stderr fileHandleForReading] readDataToEndOfFile]; + NSString *errorOutput = [[NSString alloc] initWithData:errorData encoding:NSUTF8StringEncoding]; + dispatch_sync(dispatch_get_main_queue(), ^() { + taskTerminatedHandle(output, errorOutput); + }); + [output release]; + [errorOutput release]; + } }; CefRefPtr stdoutFunction = options->GetValue("stdout"); if (stdoutFunction->IsFunction()) { - stdout.fileHandleForReading.writeabilityHandler = ^(NSFileHandle *fileHandle) { - NSData *data = [fileHandle availableData]; - NSString *contents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - dispatch_sync(dispatch_get_main_queue(), ^() { - outputHandle(contents, stdoutFunction); - }); - [contents release]; + stdout.fileHandleForReading.readabilityHandler = ^(NSFileHandle *fileHandle) { + @synchronized(task) { + NSData *data = [fileHandle availableData]; + NSString *contents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + dispatch_sync(dispatch_get_main_queue(), ^() { + outputHandle(contents, stdoutFunction); + }); + [contents release]; + } }; } CefRefPtr stderrFunction = options->GetValue("stderr"); if (stderrFunction->IsFunction()) { - stderr.fileHandleForReading.writeabilityHandler = ^(NSFileHandle *fileHandle) { - NSData *data = [fileHandle availableData]; - NSString *contents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - dispatch_sync(dispatch_get_main_queue(), ^() { - outputHandle(contents, stderrFunction); - }); - [contents release]; + stderr.fileHandleForReading.readabilityHandler = ^(NSFileHandle *fileHandle) { + @synchronized(task) { + NSData *data = [fileHandle availableData]; + NSString *contents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + dispatch_sync(dispatch_get_main_queue(), ^() { + outputHandle(contents, stderrFunction); + }); + [contents release]; + } }; }