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 "InjectedBundle.h" 30#include "QtBuiltinBundle.h" 31#include "QtNetworkAccessManager.h" 32#include "SeccompFiltersWebProcessQt.h" 33#include "WKBundleAPICast.h" 34#include "WebProcessCreationParameters.h" 35 36#include <QCoreApplication> 37#include <QNetworkAccessManager> 38#include <QNetworkCookieJar> 39#include <QNetworkDiskCache> 40#include <WebCore/CookieJarQt.h> 41#include <WebCore/FileSystem.h> 42#include <WebCore/MemoryCache.h> 43#include <WebCore/PageCache.h> 44#include <WebCore/RuntimeEnabledFeatures.h> 45 46#if defined(Q_OS_MACX) 47#include <dispatch/dispatch.h> 48#include <mach/host_info.h> 49#include <mach/mach.h> 50#include <mach/mach_error.h> 51#elif !defined(Q_OS_WIN) 52#include <unistd.h> 53#endif 54 55using namespace WebCore; 56 57namespace WebKit { 58 59static uint64_t physicalMemorySizeInBytes() 60{ 61 static uint64_t physicalMemorySize = 0; 62 63 if (!physicalMemorySize) { 64#if defined(Q_OS_MACX) 65 host_basic_info_data_t hostInfo; 66 mach_port_t host = mach_host_self(); 67 mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; 68 kern_return_t r = host_info(host, HOST_BASIC_INFO, (host_info_t)&hostInfo, &count); 69 mach_port_deallocate(mach_task_self(), host); 70 71 if (r == KERN_SUCCESS) 72 physicalMemorySize = hostInfo.max_mem; 73 74#elif defined(Q_OS_WIN) 75 MEMORYSTATUSEX statex; 76 statex.dwLength = sizeof(statex); 77 GlobalMemoryStatusEx(&statex); 78 physicalMemorySize = static_cast<uint64_t>(statex.ullTotalPhys); 79 80#else 81 long pageSize = sysconf(_SC_PAGESIZE); 82 long numberOfPages = sysconf(_SC_PHYS_PAGES); 83 84 if (pageSize > 0 && numberOfPages > 0) 85 physicalMemorySize = static_cast<uint64_t>(pageSize) * static_cast<uint64_t>(numberOfPages); 86 87#endif 88 } 89 return physicalMemorySize; 90} 91 92void WebProcess::platformSetCacheModel(CacheModel cacheModel) 93{ 94 uint64_t physicalMemorySizeInMegabytes = physicalMemorySizeInBytes() / 1024 / 1024; 95 96 // The Mac port of WebKit2 uses a fudge factor of 1000 here to account for misalignment, however, 97 // that tends to overestimate the memory quite a bit (1 byte misalignment ~ 48 MiB misestimation). 98 // We use 1024 * 1023 for now to keep the estimation error down to +/- ~1 MiB. 99 QNetworkDiskCache* diskCache = qobject_cast<QNetworkDiskCache*>(m_networkAccessManager->cache()); 100 uint64_t freeVolumeSpace = !diskCache ? 0 : WebCore::getVolumeFreeSizeForPath(diskCache->cacheDirectory().toLocal8Bit().constData()) / 1024 / 1023; 101 102 // The following variables are initialised to 0 because WebProcess::calculateCacheSizes might not 103 // set them in some rare cases. 104 unsigned cacheTotalCapacity = 0; 105 unsigned cacheMinDeadCapacity = 0; 106 unsigned cacheMaxDeadCapacity = 0; 107 double deadDecodedDataDeletionInterval = 0; 108 unsigned pageCacheCapacity = 0; 109 unsigned long urlCacheMemoryCapacity = 0; 110 unsigned long urlCacheDiskCapacity = 0; 111 112 calculateCacheSizes(cacheModel, physicalMemorySizeInMegabytes, freeVolumeSpace, 113 cacheTotalCapacity, cacheMinDeadCapacity, cacheMaxDeadCapacity, deadDecodedDataDeletionInterval, 114 pageCacheCapacity, urlCacheMemoryCapacity, urlCacheDiskCapacity); 115 116 if (diskCache) 117 diskCache->setMaximumCacheSize(urlCacheDiskCapacity); 118 119 memoryCache()->setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity); 120 memoryCache()->setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval); 121 122 pageCache()->setCapacity(pageCacheCapacity); 123 124 // FIXME: Implement hybrid in-memory- and disk-caching as e.g. the Mac port does. 125} 126 127void WebProcess::platformClearResourceCaches(ResourceCachesToClear) 128{ 129} 130 131#if defined(Q_OS_MACX) 132static void parentProcessDiedCallback(void*) 133{ 134 QCoreApplication::quit(); 135} 136#endif 137 138void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::MessageDecoder&) 139{ 140#if ENABLE(SECCOMP_FILTERS) 141 { 142 WebKit::SeccompFiltersWebProcessQt seccompFilters(parameters); 143 seccompFilters.initialize(); 144 } 145#endif 146 147 m_networkAccessManager = new QtNetworkAccessManager(this); 148 149 if (!parameters.cookieStorageDirectory.isEmpty()) { 150 WebCore::SharedCookieJarQt* jar = WebCore::SharedCookieJarQt::create(parameters.cookieStorageDirectory); 151 m_networkAccessManager->setCookieJar(jar); 152 // Do not let QNetworkAccessManager delete the jar. 153 jar->setParent(0); 154 } 155 156 if (!parameters.diskCacheDirectory.isEmpty()) { 157 QNetworkDiskCache* diskCache = new QNetworkDiskCache(); 158 diskCache->setCacheDirectory(parameters.diskCacheDirectory); 159 // The m_networkAccessManager takes ownership of the diskCache object upon the following call. 160 m_networkAccessManager->setCache(diskCache); 161 } 162 163#if defined(Q_OS_MACX) 164 pid_t ppid = getppid(); 165 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 166 dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, ppid, DISPATCH_PROC_EXIT, queue); 167 if (source) { 168 dispatch_source_set_event_handler_f(source, parentProcessDiedCallback); 169 dispatch_resume(source); 170 } 171#endif 172 173 WebCore::RuntimeEnabledFeatures::setSpeechInputEnabled(false); 174 175 // We'll only install the Qt builtin bundle if we don't have one given by the UI process. 176 // Currently only WTR provides its own bundle. 177 if (parameters.injectedBundlePath.isEmpty()) { 178 m_injectedBundle = InjectedBundle::create(String()); 179 m_injectedBundle->setSandboxExtension(SandboxExtension::create(parameters.injectedBundlePathExtensionHandle)); 180 QtBuiltinBundle::shared().initialize(toAPI(m_injectedBundle.get())); 181 } 182} 183 184void WebProcess::platformTerminate() 185{ 186 delete m_networkAccessManager; 187 m_networkAccessManager = 0; 188 WebCore::SharedCookieJarQt::shared()->destroy(); 189} 190 191} // namespace WebKit 192