Changeset 28006 in webkit
- Timestamp:
- Nov 24, 2007, 3:48:52 PM (18 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r28005 r28006 1 2007-11-24 Mark Rowe <mrowe@apple.com> 2 3 Reviewed by Tim Hatcher. 4 5 Fix <rdar://problem/5432686> 333MB RPRVT seems to leak @ www.43folders.com (1hr plug-in stream). 6 http://bugs.webkit.org/show_bug.cgi?id=13705 7 8 Don't buffer the entire stream contents in memory in the ResourceLoader. 9 10 * loader/mac/NetscapePlugInStreamLoaderMac.mm: 11 (WebCore::NetscapePlugInStreamLoader::NetscapePlugInStreamLoader): 12 (WebCore::NetscapePlugInStreamLoader::didFinishLoading): 13 * loader/mac/WebPlugInStreamLoaderDelegate.h: 14 1 15 2007-11-23 Adam Roben <aroben@apple.com> 2 16 -
trunk/WebCore/loader/mac/NetscapePlugInStreamLoaderMac.mm
r25274 r28006 43 43 , m_stream(stream) 44 44 { 45 setShouldBufferData(false); 45 46 } 46 47 … … 107 108 108 109 m_documentLoader->removePlugInStreamLoader(this); 109 NSData *data = resourceData()->createNSData(); 110 [m_stream.get() finishedLoadingWithData:data]; 111 [data release]; 110 [m_stream.get() finishedLoading]; 112 111 ResourceLoader::didFinishLoading(); 113 112 } -
trunk/WebCore/loader/mac/WebPlugInStreamLoaderDelegate.h
r16967 r28006 42 42 43 43 - (void)receivedData:(NSData *)data; 44 - (void)finishedLoading WithData:(NSData *)data;44 - (void)finishedLoading; 45 45 46 46 @end -
trunk/WebKit/mac/ChangeLog
r27995 r28006 1 2007-11-24 Mark Rowe <mrowe@apple.com> 2 3 Reviewed by Tim Hatcher. 4 5 Fix <rdar://problem/5432686> 333MB RPRVT seems to leak @ www.43folders.com (1hr plug-in stream). 6 http://bugs.webkit.org/show_bug.cgi?id=13705 7 8 Have NP_ASFILE and NP_ASFILEONLY streams write the data to disk as they receive it rather than 9 dumping the data to disk in a single go when the stream has completed loading. On a test case 10 involving a 150MB Flash movie being streamed from a local web server this reduces memory consumption 11 on page load from around 400MB to 22MB. 12 13 The only plugin I have found that uses NP_ASFILE or NP_ASFILEONLY on the Mac is our NetscapeMoviePlugin 14 example code so the NP_ASFILE portion of this change has not had any testing with a real-world plugin. 15 16 * Plugins/WebBaseNetscapePluginStream.h: 17 * Plugins/WebBaseNetscapePluginStream.mm: 18 (-[WebBaseNetscapePluginStream initWithRequestURL:plugin:notifyData:sendNotification:]): 19 (-[WebBaseNetscapePluginStream dealloc]): 20 (-[WebBaseNetscapePluginStream finalize]): 21 (-[WebBaseNetscapePluginStream startStreamResponseURL:expectedContentLength:lastModifiedDate:MIMEType:headers:]): 22 (-[WebBaseNetscapePluginStream _destroyStream]): Update to work with paths as NSStrings. 23 (-[WebBaseNetscapePluginStream _deliverDataToFile:]): Open the file if it is not already open, and write any data 24 to disk. 25 (-[WebBaseNetscapePluginStream finishedLoading]): If the stream is NP_ASFILE or NP_ASFILEONLY we need to ensure 26 that the file exists before _destroyStream passes it to the plugin. Simulating the arrival of an empty data block 27 ensure that the file will be created if it has not already. 28 (-[WebBaseNetscapePluginStream receivedData:]): 29 (CarbonPathFromPOSIXPath): 30 * Plugins/WebBaseNetscapePluginView.mm: 31 (-[WebBaseNetscapePluginView pluginViewFinishedLoading:]): Data is dealt with incrementally so there's no need to pass 32 it to finishedLoading. 33 (-[WebBaseNetscapePluginView evaluateJavaScriptPluginRequest:]): Ditto. 34 1 35 2007-11-23 Oliver Hunt <oliver@apple.com> 2 36 -
trunk/WebKit/mac/Plugins/WebBaseNetscapePluginStream.h
r24947 r28006 46 46 int32 offset; 47 47 NPStream stream; 48 char *path; 48 NSString *path; 49 int fileDescriptor; 49 50 BOOL sendNotification; 50 51 void *notifyData; -
trunk/WebKit/mac/Plugins/WebBaseNetscapePluginStream.mm
r25024 r28006 43 43 #define WEB_REASON_NONE -1 44 44 45 static char *CarbonPathFromPOSIXPath(const char*posixPath);45 static NSString *CarbonPathFromPOSIXPath(NSString *posixPath); 46 46 47 47 typedef HashMap<NPStream*, NPP> StreamMap; … … 118 118 notifyData = theNotifyData; 119 119 sendNotification = flag; 120 fileDescriptor = -1; 120 121 121 122 streams().add(&stream, thePlugin); … … 134 135 // The stream file should have been deleted, and the path freed, in -_destroyStream 135 136 ASSERT(!path); 137 ASSERT(fileDescriptor == -1); 136 138 137 139 [requestURL release]; … … 158 160 // The stream file should have been deleted, and the path freed, in -_destroyStream 159 161 ASSERT(!path); 162 ASSERT(fileDescriptor == -1); 160 163 161 164 free((void *)stream.url); … … 258 261 offset = 0; 259 262 reason = WEB_REASON_NONE; 263 // FIXME: If WebNetscapePluginStream called our initializer we wouldn't have to do this here. 264 fileDescriptor = -1; 260 265 261 266 // FIXME: Need a way to check if stream is seekable … … 365 370 if (stream.ndata != nil) { 366 371 if (reason == NPRES_DONE && (transferMode == NP_ASFILE || transferMode == NP_ASFILEONLY)) { 372 ASSERT(fileDescriptor == -1); 367 373 ASSERT(path != NULL); 368 char*carbonPath = CarbonPathFromPOSIXPath(path);374 NSString *carbonPath = CarbonPathFromPOSIXPath(path); 369 375 ASSERT(carbonPath != NULL); 370 376 WebBaseNetscapePluginView *pv = pluginView; 371 377 [pv willCallPlugInFunction]; 372 NPP_StreamAsFile(plugin, &stream, carbonPath);378 NPP_StreamAsFile(plugin, &stream, [carbonPath fileSystemRepresentation]); 373 379 [pv didCallPlugInFunction]; 374 380 … … 377 383 // (the stream destruction function), so there can be no expectation that a plugin will read the stream 378 384 // file asynchronously after NPP_StreamAsFile() is called. 379 unlink( path);380 free(path);381 path = NULL;385 unlink([path fileSystemRepresentation]); 386 [path release]; 387 path = nil; 382 388 LOG(Plugins, "NPP_StreamAsFile responseURL=%@ path=%s", responseURL, carbonPath); 383 free(carbonPath);384 389 385 390 if (isTerminated) … … 453 458 [self setPlugin:NULL]; 454 459 [self release]; 455 }456 457 - (void)finishedLoadingWithData:(NSData *)data458 {459 if (!stream.ndata)460 return;461 462 if ((transferMode == NP_ASFILE || transferMode == NP_ASFILEONLY) && !path) {463 path = strdup("/tmp/WebKitPlugInStreamXXXXXX");464 int fd = mkstemp(path);465 if (fd == -1) {466 // This should almost never happen.467 LOG_ERROR("can't make temporary file, almost certainly a problem with /tmp");468 // This is not a network error, but the only error codes are "network error" and "user break".469 [self _destroyStreamWithReason:NPRES_NETWORK_ERR];470 free(path);471 path = NULL;472 return;473 }474 int dataLength = [data length];475 if (dataLength > 0) {476 int byteCount = write(fd, [data bytes], dataLength);477 if (byteCount != dataLength) {478 // This happens only rarely, when we are out of disk space or have a disk I/O error.479 LOG_ERROR("error writing to temporary file, errno %d", errno);480 close(fd);481 // This is not a network error, but the only error codes are "network error" and "user break".482 [self _destroyStreamWithReason:NPRES_NETWORK_ERR];483 free(path);484 path = NULL;485 return;486 }487 }488 close(fd);489 }490 491 [self _destroyStreamWithReason:NPRES_DONE];492 460 } 493 461 … … 553 521 } 554 522 523 - (void)_deliverDataToFile:(NSData *)data 524 { 525 if (fileDescriptor == -1 && !path) { 526 NSString *temporaryFileMask = [NSTemporaryDirectory() stringByAppendingPathComponent:@"WebKitPlugInStreamXXXXXX"]; 527 char *temporaryFileName = strdup([temporaryFileMask fileSystemRepresentation]); 528 fileDescriptor = mkstemp(temporaryFileName); 529 if (fileDescriptor == -1) { 530 LOG_ERROR("Can't create a temporary file."); 531 // This is not a network error, but the only error codes are "network error" and "user break". 532 [self _destroyStreamWithReason:NPRES_NETWORK_ERR]; 533 free(temporaryFileName); 534 return; 535 } 536 537 path = [[NSString stringWithUTF8String:temporaryFileName] retain]; 538 free(temporaryFileName); 539 } 540 541 int dataLength = [data length]; 542 if (!dataLength) 543 return; 544 545 int byteCount = write(fileDescriptor, [data bytes], dataLength); 546 if (byteCount != dataLength) { 547 // This happens only rarely, when we are out of disk space or have a disk I/O error. 548 LOG_ERROR("error writing to temporary file, errno %d", errno); 549 close(fileDescriptor); 550 fileDescriptor = -1; 551 552 // This is not a network error, but the only error codes are "network error" and "user break". 553 [self _destroyStreamWithReason:NPRES_NETWORK_ERR]; 554 [path release]; 555 path = nil; 556 } 557 } 558 559 - (void)finishedLoading 560 { 561 if (!stream.ndata) 562 return; 563 564 if (transferMode == NP_ASFILE || transferMode == NP_ASFILEONLY) { 565 // Fake the delivery of an empty data to ensure that the file has been created 566 [self _deliverDataToFile:[NSData data]]; 567 if (fileDescriptor != -1) 568 close(fileDescriptor); 569 fileDescriptor = -1; 570 } 571 572 [self _destroyStreamWithReason:NPRES_DONE]; 573 } 574 555 575 - (void)receivedData:(NSData *)data 556 576 { … … 564 584 [self _deliverData]; 565 585 } 586 if (transferMode == NP_ASFILE || transferMode == NP_ASFILEONLY) 587 [self _deliverDataToFile:data]; 588 566 589 } 567 590 568 591 @end 569 592 570 static char *CarbonPathFromPOSIXPath(const char*posixPath)593 static NSString *CarbonPathFromPOSIXPath(NSString *posixPath) 571 594 { 572 595 // Doesn't add a trailing colon for directories; this is a problem for paths to a volume, 573 596 // so this function would need to be revised if we ever wanted to call it with that. 574 597 575 CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8 *)posixPath, strlen(posixPath), false); 576 if (url) { 577 CFStringRef hfsPath = CFURLCopyFileSystemPath(url, kCFURLHFSPathStyle); 578 CFRelease(url); 579 if (hfsPath) { 580 CFIndex bufSize = CFStringGetMaximumSizeOfFileSystemRepresentation(hfsPath); 581 char* filename = static_cast<char*>(malloc(bufSize)); 582 CFStringGetFileSystemRepresentation(hfsPath, filename, bufSize); 583 CFRelease(hfsPath); 584 return filename; 585 } 586 } 587 588 return NULL; 598 CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:posixPath]; 599 if (!url) 600 return nil; 601 602 NSString *hfsPath = NSMakeCollectable(CFURLCopyFileSystemPath(url, kCFURLHFSPathStyle)); 603 return [hfsPath autorelease]; 589 604 } 590 605 -
trunk/WebKit/mac/Plugins/WebBaseNetscapePluginView.mm
r27745 r28006 2010 2010 2011 2011 if ([self isStarted]) 2012 [_manualStream finishedLoading WithData:[[self dataSource] data]];2012 [_manualStream finishedLoading]; 2013 2013 } 2014 2014 … … 2082 2082 headers:nil]; 2083 2083 [stream receivedData:JSData]; 2084 [stream finishedLoading WithData:JSData];2084 [stream finishedLoading]; 2085 2085 [stream release]; 2086 2086 }
Note:
See TracChangeset
for help on using the changeset viewer.