1/* 2 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#import "config.h" 27#import "DiskCacheMonitor.h" 28 29#import "NetworkConnectionToWebProcess.h" 30#import "NetworkProcessConnectionMessages.h" 31#import "NetworkResourceLoader.h" 32#import "WebCoreArgumentCoders.h" 33#import <wtf/PassOwnPtr.h> 34 35#ifdef __has_include 36#if __has_include(<CFNetwork/CFURLCachePriv.h>) 37#include <CFNetwork/CFURLCachePriv.h> 38#endif 39#endif 40 41#if (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090) 42 43typedef void (^CFCachedURLResponseCallBackBlock)(CFCachedURLResponseRef); 44extern "C" void _CFCachedURLResponseSetBecameFileBackedCallBackBlock(CFCachedURLResponseRef, CFCachedURLResponseCallBackBlock, dispatch_queue_t); 45 46using namespace WebCore; 47 48namespace WebKit { 49 50// The maximum number of seconds we'll try to wait for a resource to be disk cached before we forget the request. 51static const double diskCacheMonitorTimeout = 20; 52 53void DiskCacheMonitor::monitorFileBackingStoreCreation(CFCachedURLResponseRef cachedResponse, NetworkResourceLoader* loader) 54{ 55 if (!cachedResponse) 56 return; 57 58 ASSERT(loader); 59 60 new DiskCacheMonitor(cachedResponse, loader); // Balanced by adoptPtr in the blocks setup in the constructor, one of which is guaranteed to run. 61} 62 63DiskCacheMonitor::DiskCacheMonitor(CFCachedURLResponseRef cachedResponse, NetworkResourceLoader* loader) 64 : m_connectionToWebProcess(loader->connectionToWebProcess()) 65 , m_resourceRequest(loader->request()) 66 , m_sessionID(loader->sessionID()) 67{ 68 ASSERT(RunLoop::isMain()); 69 70 // Set up a delayed callback to cancel this monitor if the resource hasn't been cached yet. 71 __block DiskCacheMonitor* rawMonitor = this; 72 73 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * diskCacheMonitorTimeout), dispatch_get_main_queue(), ^{ 74 adoptPtr(rawMonitor); // Balanced by `new DiskCacheMonitor` in monitorFileBackingStoreCreation. 75 rawMonitor = 0; 76 }); 77 78 // Set up the disk caching callback to create the ShareableResource and send it to the WebProcess. 79 CFCachedURLResponseCallBackBlock block = ^(CFCachedURLResponseRef cachedResponse) 80 { 81 // If the monitor isn't there then it timed out before this resource was cached to disk. 82 if (!rawMonitor) 83 return; 84 85 OwnPtr<DiskCacheMonitor> monitor = adoptPtr(rawMonitor); // Balanced by `new DiskCacheMonitor` in monitorFileBackingStoreCreation. 86 rawMonitor = 0; 87 88 ShareableResource::Handle handle; 89 NetworkResourceLoader::tryGetShareableHandleFromCFURLCachedResponse(handle, cachedResponse); 90 if (handle.isNull()) 91 return; 92 93 monitor->send(Messages::NetworkProcessConnection::DidCacheResource(monitor->resourceRequest(), handle, m_sessionID)); 94 }; 95 96 _CFCachedURLResponseSetBecameFileBackedCallBackBlock(cachedResponse, block, dispatch_get_main_queue()); 97} 98 99IPC::Connection* DiskCacheMonitor::messageSenderConnection() 100{ 101 return m_connectionToWebProcess->connection(); 102} 103 104uint64_t DiskCacheMonitor::messageSenderDestinationID() 105{ 106 return 0; 107} 108 109} // namespace WebKit 110 111#endif 112