From 90f34b6d84f38b6fa4bc52784a47a4a970ee3156 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Sun, 5 Apr 2020 20:23:06 -0400 Subject: [PATCH] Fix loading of large source files. BSSourceView would wait for the php NSTask to terminate before reading from the stdout pipe. But if the highlighting output was larger than the NSPipe buffer, php would fill the buffer and hang in write() waiting for available space. Instead, start reading the stdout pipe immediately after launching the task. --- CHANGES | 1 + Source/BSSourceView.mm | 30 ++++++++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index 005eec3..4bd0c0c 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,7 @@ MacGDBp CHANGE LOG - Fix: #260 Use macOS standard colors for syntax highlighting for better dark- mode compatibility. - Change: Improve toolbar buttons under dark mode. +- Fix: #261 Large source files would fail to load. 2.0 Beta 1 ##################### diff --git a/Source/BSSourceView.mm b/Source/BSSourceView.mm index 7899dfc..048dd3a 100644 --- a/Source/BSSourceView.mm +++ b/Source/BSSourceView.mm @@ -219,15 +219,24 @@ NSString* ColorHEXStringINIDirective(NSString* directive, NSColor* color) { ]]; [task setStandardOutput:outPipe]; [task setStandardError:errPipe]; - [task setTerminationHandler:^(NSTask*) { - NSMutableAttributedString* source; + [task setTerminationHandler:^(NSTask* taskBlock) { + if (task.terminationStatus != 0) { + NSLog(@"Failed to highlight PHP file %@. Termination status=%d. stderr: %@", + filePath, taskBlock.terminationStatus, [[errPipe fileHandleForReading] readDataToEndOfFile]); + } + }]; + [task launch]; - if (task.terminationStatus == 0) { - NSData* data = [[outPipe fileHandleForReading] readDataToEndOfFile]; - source = - [[NSMutableAttributedString alloc] initWithHTML:data - options:@{ NSCharacterEncodingDocumentAttribute : @(NSUTF8StringEncoding) } - documentAttributes:nil]; + // Start reading the stdout pipe on a background queue. This is separate + // from the terminiationHandler, since a large file could be greater than + // the pipe buffer. + dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ + NSMutableAttributedString* source; + NSData* data = [[outPipe fileHandleForReading] readDataToEndOfFile]; + if (data.length) { + source = [[NSMutableAttributedString alloc] initWithHTML:data + options:@{ NSCharacterEncodingDocumentAttribute : @(NSUTF8StringEncoding) } + documentAttributes:nil]; // PHP uses   in the highlighted output, which should be converted // back to normal spaces. @@ -237,8 +246,6 @@ NSString* ColorHEXStringINIDirective(NSString* directive, NSColor* color) { // Override the default font from Courier. [source addAttributes:@{ NSFontAttributeName : [[self class] sourceFont] } range:NSMakeRange(0, source.length)]; - } else { - NSLog(@"Failed to highlight PHP file %@: %@", filePath, [[errPipe fileHandleForReading] readDataToEndOfFile]); } dispatch_async(dispatch_get_main_queue(), ^{ @@ -253,8 +260,7 @@ NSString* ColorHEXStringINIDirective(NSString* directive, NSColor* color) { if (handler) handler(); }); - }]; - [task launch]; + }); } @catch (NSException* exception) { // If the PHP executable is not available then the NSTask will throw an exception NSLog(@"Failed to highlight file: %@", exception); -- 2.22.5