1 /* 2 * Copyright (C) 2010 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 #include "config.h" 27 #include "WebProcess.h" 28 29 #include "WebCookieManager.h" 30 #include "WebPage.h" 31 #include "WebProcessCreationParameters.h" 32 #include <WebCore/FileSystem.h> 33 #include <WebCore/MemoryCache.h> 34 #include <WebCore/PageCache.h> 35 #include <WebCore/Settings.h> 36 #include <wtf/text/WTFString.h> 37 38 #if USE(CFNETWORK) 39 #include <CFNetwork/CFURLCachePriv.h> 40 #include <CFNetwork/CFURLProtocolPriv.h> 41 #include <WebCore/CookieStorageCFNet.h> 42 #include <WebKitSystemInterface/WebKitSystemInterface.h> 43 #include <wtf/RetainPtr.h> 44 #endif 45 46 using namespace WebCore; 47 using namespace std; 48 49 namespace WebKit { 50 51 static uint64_t memorySize() 52 { 53 MEMORYSTATUSEX statex; 54 statex.dwLength = sizeof(statex); 55 GlobalMemoryStatusEx(&statex); 56 return statex.ullTotalPhys; 57 } 58 59 static uint64_t volumeFreeSize(CFStringRef cfstringPath) 60 { 61 WTF::String path(cfstringPath); 62 ULARGE_INTEGER freeBytesToCaller; 63 BOOL result = GetDiskFreeSpaceExW((LPCWSTR)path.charactersWithNullTermination(), &freeBytesToCaller, 0, 0); 64 if (!result) 65 return 0; 66 return freeBytesToCaller.QuadPart; 67 } 68 69 void WebProcess::platformSetCacheModel(CacheModel cacheModel) 70 { 71 #if USE(CFNETWORK) 72 RetainPtr<CFStringRef> cfurlCacheDirectory(AdoptCF, wkCopyFoundationCacheDirectory()); 73 if (!cfurlCacheDirectory) 74 cfurlCacheDirectory.adoptCF(WebCore::localUserSpecificStorageDirectory().createCFString()); 75 76 // As a fudge factor, use 1000 instead of 1024, in case the reported byte 77 // count doesn't align exactly to a megabyte boundary. 78 uint64_t memSize = memorySize() / 1024 / 1000; 79 uint64_t diskFreeSize = volumeFreeSize(cfurlCacheDirectory.get()) / 1024 / 1000; 80 81 unsigned cacheTotalCapacity = 0; 82 unsigned cacheMinDeadCapacity = 0; 83 unsigned cacheMaxDeadCapacity = 0; 84 double deadDecodedDataDeletionInterval = 0; 85 unsigned pageCacheCapacity = 0; 86 unsigned long urlCacheMemoryCapacity = 0; 87 unsigned long urlCacheDiskCapacity = 0; 88 89 calculateCacheSizes(cacheModel, memSize, diskFreeSize, 90 cacheTotalCapacity, cacheMinDeadCapacity, cacheMaxDeadCapacity, deadDecodedDataDeletionInterval, 91 pageCacheCapacity, urlCacheMemoryCapacity, urlCacheDiskCapacity); 92 93 memoryCache()->setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity); 94 memoryCache()->setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval); 95 pageCache()->setCapacity(pageCacheCapacity); 96 97 RetainPtr<CFURLCacheRef> cfurlCache(AdoptCF, CFURLCacheCopySharedURLCache()); 98 CFURLCacheSetMemoryCapacity(cfurlCache.get(), urlCacheMemoryCapacity); 99 CFURLCacheSetDiskCapacity(cfurlCache.get(), max<unsigned long>(urlCacheDiskCapacity, CFURLCacheDiskCapacity(cfurlCache.get()))); // Don't shrink a big disk cache, since that would cause churn. 100 #endif 101 } 102 103 void WebProcess::platformClearResourceCaches(ResourceCachesToClear cachesToClear) 104 { 105 #if USE(CFNETWORK) 106 if (cachesToClear == InMemoryResourceCachesOnly) 107 return; 108 CFURLCacheRemoveAllCachedResponses(RetainPtr<CFURLCacheRef>(AdoptCF, CFURLCacheCopySharedURLCache()).get()); 109 #endif 110 } 111 112 void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder*) 113 { 114 setShouldPaintNativeControls(parameters.shouldPaintNativeControls); 115 116 #if USE(CFNETWORK) 117 RetainPtr<CFStringRef> cachePath(AdoptCF, parameters.cfURLCachePath.createCFString()); 118 if (!cachePath) 119 return; 120 121 CFIndex cacheDiskCapacity = parameters.cfURLCacheDiskCapacity; 122 CFIndex cacheMemoryCapacity = parameters.cfURLCacheMemoryCapacity; 123 RetainPtr<CFURLCacheRef> uiProcessCache(AdoptCF, CFURLCacheCreate(kCFAllocatorDefault, cacheMemoryCapacity, cacheDiskCapacity, cachePath.get())); 124 CFURLCacheSetSharedURLCache(uiProcessCache.get()); 125 #endif 126 127 WebCookieManager::shared().setHTTPCookieAcceptPolicy(parameters.initialHTTPCookieAcceptPolicy); 128 } 129 130 void WebProcess::platformTerminate() 131 { 132 } 133 134 void WebProcess::setShouldPaintNativeControls(bool shouldPaintNativeControls) 135 { 136 #if USE(SAFARI_THEME) 137 Settings::setShouldPaintNativeControls(shouldPaintNativeControls); 138 #endif 139 } 140 141 struct EnumWindowsContext { 142 DWORD currentThreadID; 143 Vector<HWND>* windows; 144 }; 145 146 static BOOL CALLBACK addWindowToVectorIfOwnedByCurrentThread(HWND window, LPARAM lParam) 147 { 148 EnumWindowsContext* context = reinterpret_cast<EnumWindowsContext*>(lParam); 149 150 if (::GetWindowThreadProcessId(window, 0) != context->currentThreadID) 151 return TRUE; 152 153 context->windows->append(window); 154 return TRUE; 155 } 156 157 Vector<HWND> WebProcess::windowsToReceiveSentMessagesWhileWaitingForSyncReply() 158 { 159 Vector<HWND> windows; 160 161 // Any non-message-only window created by this thread needs to receive sent messages while we 162 // wait for a sync reply. Otherwise we could deadlock with the UI process if, e.g., the focus 163 // window changes. See <http://webkit.org/b/58239>. 164 165 EnumWindowsContext context; 166 context.currentThreadID = ::GetCurrentThreadId(); 167 context.windows = &windows; 168 169 // Start out with top-level windows created by this thread (like Flash's hidden 170 // SWFlash_PlaceholderX top-level windows). 171 ::EnumThreadWindows(context.currentThreadID, addWindowToVectorIfOwnedByCurrentThread, reinterpret_cast<LPARAM>(&context)); 172 173 // Also include any descendants of those top-level windows. 174 size_t topLevelWindowCount = windows.size(); 175 for (size_t i = 0; i < topLevelWindowCount; ++i) 176 ::EnumChildWindows(windows[i], addWindowToVectorIfOwnedByCurrentThread, reinterpret_cast<LPARAM>(&context)); 177 178 // Also include any descendants of the WebPages' windows which we've created (e.g., for windowed plugins). 179 HashMap<uint64_t, RefPtr<WebPage> >::const_iterator::Values end = m_pageMap.end(); 180 for (HashMap<uint64_t, RefPtr<WebPage> >::const_iterator::Values it = m_pageMap.begin(); it != end; ++it) 181 ::EnumChildWindows((*it)->nativeWindow(), addWindowToVectorIfOwnedByCurrentThread, reinterpret_cast<LPARAM>(&context)); 182 183 return windows; 184 } 185 186 } // namespace WebKit 187