From a893a2adef3e7ab48cc28bb7cedbf2674cd91146 Mon Sep 17 00:00:00 2001 From: Allan Odgaard Date: Sun, 14 Aug 2016 11:20:35 +0200 Subject: [PATCH] =?UTF-8?q?Use=20NSURLProtocol=E2=80=99s=20setProperty:for?= =?UTF-8?q?Key:inRequest:=20for=20associated=20data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This simplifies our code though it seems like the lifetime of the data is much longer than the request it is associated with. --- Frameworks/HTMLOutput/src/HTMLOutput.mm | 78 +++++-------------------- 1 file changed, 14 insertions(+), 64 deletions(-) diff --git a/Frameworks/HTMLOutput/src/HTMLOutput.mm b/Frameworks/HTMLOutput/src/HTMLOutput.mm index 7ecb7aa3..4a1f5c74 100644 --- a/Frameworks/HTMLOutput/src/HTMLOutput.mm +++ b/Frameworks/HTMLOutput/src/HTMLOutput.mm @@ -5,50 +5,7 @@ NSString* const kCommandRunnerURLScheme = @"x-txmt-command"; -namespace -{ - struct runners_t - { - NSInteger add_process (pid_t processId, NSFileHandle* fileHandle) - { - std::lock_guard lock(_lock); - return _records.emplace(++_next_key, (record_t){ processId, fileHandle }).first->first; - } - - std::pair remove_process (NSInteger key) - { - std::lock_guard lock(_lock); - auto iter = _records.find(key); - if(iter == _records.end()) - return { }; - - auto res = std::make_pair(iter->second.process_id, iter->second.file_handle); - _records.erase(iter); - return res; - } - - private: - struct record_t - { - pid_t process_id; - NSFileHandle* file_handle; - }; - - NSInteger _next_key = 0; - std::map _records; - std::mutex _lock; - }; - - runners_t& runners () - { - static runners_t runners; - return runners; - } -} - @interface CommandRunnerURLProtocol : NSURLProtocol -@property (nonatomic) pid_t processId; -@property (nonatomic) NSFileHandle* fileHandle; @end @implementation CommandRunnerURLProtocol @@ -62,26 +19,14 @@ namespace + (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)request { return request; } + (BOOL)requestIsCacheEquivalent:(NSURLRequest*)a toRequest:(NSURLRequest*)b { return NO; } -- (id)initWithRequest:(NSURLRequest*)anURLRequest cachedResponse:(NSCachedURLResponse*)aCachedURLResponse client:(id )anId -{ - if(self = [super initWithRequest:anURLRequest cachedResponse:aCachedURLResponse client:anId]) - { - NSInteger key; - NSString* jobString = [[[anURLRequest URL] path] lastPathComponent]; - NSScanner* scanner = [NSScanner scannerWithString:jobString]; - if([scanner scanInteger:&key] && scanner.scanLocation == [jobString length]) - std::tie(_processId, _fileHandle) = runners().remove_process(key); - } - return self; -} - // ============================================= // = These methods might be called in a thread = // ============================================= - (void)startLoading { - if(!_fileHandle) + NSFileHandle* fileHandle = [NSURLProtocol propertyForKey:@"fileHandle" inRequest:self.request]; + if(!fileHandle) { NSURLResponse* response = [[NSHTTPURLResponse alloc] initWithURL:[[self request] URL] statusCode:404 HTTPVersion:@"HTTP/1.1" headerFields:nil]; [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; @@ -97,11 +42,10 @@ namespace static std::string const dummy(""); [[self client] URLProtocol:self didLoadData:[NSData dataWithBytes:dummy.data() length:dummy.size()]]; - NSFileHandle* fh = _fileHandle; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ char buf[8192]; int len; - while((len = read(fh.fileDescriptor, buf, sizeof(buf))) > 0) + while((len = read(fileHandle.fileDescriptor, buf, sizeof(buf))) > 0) { NSData* data = [NSData dataWithBytesNoCopy:buf length:len freeWhenDone:NO]; [[self client] URLProtocol:self didLoadData:data]; @@ -110,15 +54,16 @@ namespace if(len == -1) perror("read"); - [fh closeFile]; + [fileHandle closeFile]; [[self client] URLProtocolDidFinishLoading:self]; }); } - (void)stopLoading { - [_fileHandle closeFile]; - oak::kill_process_group_in_background(_processId); + [[NSURLProtocol propertyForKey:@"fileHandle" inRequest:self.request] closeFile]; + if(pid_t pid = [[NSURLProtocol propertyForKey:@"processIdentifier" inRequest:self.request] intValue]) + oak::kill_process_group_in_background(pid); } @end @@ -157,6 +102,11 @@ NSURLRequest* URLRequestForCommandRunner (command::runner_ptr aRunner) NSPipe* pipe = [NSPipe pipe]; new filehandle_callback_t(aRunner, pipe.fileHandleForWriting); - NSInteger key = runners().add_process(aRunner->process_id(), pipe.fileHandleForReading); - return [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@://job/%ld", kCommandRunnerURLScheme, key]] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:6000]; // TODO add a description parameter to the URL (based on bundle item name) + static NSInteger LastKey = 0; + + NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@://job/%ld", kCommandRunnerURLScheme, ++LastKey]] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:6000]; + [NSURLProtocol setProperty:pipe.fileHandleForReading forKey:@"fileHandle" inRequest:request]; + [NSURLProtocol setProperty:@(aRunner->process_id()) forKey:@"processIdentifier" inRequest:request]; + // TODO Add a description (based on bundle item name) + return request; }