Changeset 241855 in webkit
- Timestamp:
- Feb 20, 2019 5:25:46 PM (5 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r241853 r241855 1 2019-02-20 Chris Dumez <cdumez@apple.com> 2 3 [PSON] Make sure hung processes are not kept alive by suspended pages or process caching 4 https://bugs.webkit.org/show_bug.cgi?id=194881 5 <rdar://problem/48249014> 6 7 Reviewed by Geoffrey Garen. 8 9 After we construct a SuspendedPageProxy and before we send the IPC to the WebProcess to 10 ask it to suspend, start a 10 seconds timer. If the process does not answer the request 11 to suspend before the timer fires, we destroy the SuspendedPageProxy so that we do not 12 keep a hung process around. 13 14 For the WebProcessCache, we now call WebProcessProxy::isResponsive() on the process 15 before adding it to the cache. Internally, this relies on an IPC handshake with the 16 WebProcess. If the process is not responsive, we do not add it to the cache and we 17 shut it down. If it is responsive then we proceed normally with adding it to the 18 cache. 19 20 * UIProcess/SuspendedPageProxy.cpp: 21 (WebKit::SuspendedPageProxy::SuspendedPageProxy): 22 (WebKit::SuspendedPageProxy::didProcessRequestToSuspend): 23 (WebKit::SuspendedPageProxy::suspensionTimedOut): 24 * UIProcess/SuspendedPageProxy.h: 25 * UIProcess/WebProcessCache.cpp: 26 (WebKit::WebProcessCache::addProcessIfPossible): 27 (WebKit::WebProcessCache::addProcess): 28 * UIProcess/WebProcessCache.h: 29 * UIProcess/WebProcessProxy.cpp: 30 (WebKit::WebProcessProxy::processDidTerminateOrFailedToLaunch): 31 (WebKit::WebProcessProxy::maybeShutDown): 32 (WebKit::WebProcessProxy::isResponsive): 33 * UIProcess/WebProcessProxy.h: 34 1 35 2019-02-20 Chris Dumez <cdumez@apple.com> 2 36 -
trunk/Source/WebKit/UIProcess/SuspendedPageProxy.cpp
r241751 r241855 41 41 namespace WebKit { 42 42 using namespace WebCore; 43 44 static const Seconds suspensionTimeout { 10_s }; 43 45 44 46 #if !LOG_DISABLED … … 82 84 , m_mainFrameID(mainFrameID) 83 85 , m_registrableDomain(toRegistrableDomain(URL(URL(), item.url()))) 86 , m_suspensionTimeoutTimer(RunLoop::main(), this, &SuspendedPageProxy::suspensionTimedOut) 84 87 #if PLATFORM(IOS_FAMILY) 85 88 , m_suspensionToken(m_process->throttler().backgroundActivityToken()) … … 89 92 m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_page.pageID(), *this); 90 93 94 m_suspensionTimeoutTimer.startOneShot(suspensionTimeout); 91 95 m_process->send(Messages::WebPage::SetIsSuspended(true), m_page.pageID()); 92 96 } … … 165 169 m_suspensionState = newSuspensionState; 166 170 171 m_suspensionTimeoutTimer.stop(); 172 167 173 #if PLATFORM(IOS_FAMILY) 168 174 m_suspensionToken = nullptr; … … 184 190 } 185 191 192 void SuspendedPageProxy::suspensionTimedOut() 193 { 194 RELEASE_LOG_ERROR(ProcessSwapping, "%p - SuspendedPageProxy::suspensionTimedOut() destroying the suspended page because it failed to suspend in time", this); 195 m_process->processPool().removeSuspendedPage(*this); // Will destroy |this|. 196 } 197 186 198 void SuspendedPageProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder& decoder) 187 199 { -
trunk/Source/WebKit/UIProcess/SuspendedPageProxy.h
r241853 r241855 63 63 enum class SuspensionState : uint8_t { Suspending, FailedToSuspend, Suspended, Resumed }; 64 64 void didProcessRequestToSuspend(SuspensionState); 65 void suspensionTimedOut(); 65 66 66 67 // IPC::MessageReceiver … … 76 77 SuspensionState m_suspensionState { SuspensionState::Suspending }; 77 78 CompletionHandler<void(SuspendedPageProxy*)> m_readyToUnsuspendHandler; 79 RunLoop::Timer<SuspendedPageProxy> m_suspensionTimeoutTimer; 78 80 #if PLATFORM(IOS_FAMILY) 79 81 ProcessThrottler::BackgroundActivityToken m_suspensionToken; -
trunk/Source/WebKit/UIProcess/WebProcessCache.cpp
r241635 r241855 45 45 } 46 46 47 bool WebProcessCache::addProcess (const String& registrableDomain, Ref<WebProcessProxy>&& process)47 bool WebProcessCache::addProcessIfPossible(const String& registrableDomain, Ref<WebProcessProxy>&& process) 48 48 { 49 49 ASSERT(!registrableDomain.isEmpty()); … … 56 56 57 57 if (MemoryPressureHandler::singleton().isUnderMemoryPressure()) { 58 RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcessIfPossible(): Not caching process %i because we are under memory pressure", this, process->processIdentifier()); 59 return false; 60 } 61 62 if (m_processesPerRegistrableDomain.contains(registrableDomain)) { 63 RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcessIfPossible(): Not caching process %i because we already have a cached process for this domain", this, process->processIdentifier()); 64 return false; 65 } 66 67 RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcessIfPossible(): Checking if process %i is responsive before caching it...", this, process->processIdentifier()); 68 process->setIsInProcessCache(true); 69 process->isResponsive([process = process.copyRef(), registrableDomain](bool isResponsive) { 70 process->setIsInProcessCache(false); 71 if (!isResponsive) { 72 RELEASE_LOG_ERROR(ProcessSwapping, "%p - WebProcessCache::addProcessIfPossible(): Not caching process %i because it is not responsive", &process->processPool().webProcessCache(), process->processIdentifier()); 73 process->shutDown(); 74 return; 75 } 76 if (!process->processPool().webProcessCache().addProcess(registrableDomain, process.copyRef())) 77 process->shutDown(); 78 }); 79 return true; 80 } 81 82 bool WebProcessCache::addProcess(const String& registrableDomain, Ref<WebProcessProxy>&& process) 83 { 84 ASSERT(!process->pageCount()); 85 ASSERT(!process->provisionalPageCount()); 86 ASSERT(!process->processPool().hasSuspendedPageFor(process)); 87 88 if (!capacity()) 89 return false; 90 91 if (MemoryPressureHandler::singleton().isUnderMemoryPressure()) { 58 92 RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcess(): Not caching process %i because we are under memory pressure", this, process->processIdentifier()); 59 93 return false; … … 69 103 return std::make_unique<CachedProcess>(WTFMove(process)); 70 104 }); 71 if (!addResult.isNewEntry) 72 return false; 105 if (!addResult.isNewEntry) { 106 RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcess(): Not caching process %i because we already have a cached process for this domain", this, process->processIdentifier()); 107 return false; 108 } 73 109 74 110 RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcess: Adding process %i to WebProcess cache, cache size: [%u / %u]", this, process->processIdentifier(), size(), capacity()); -
trunk/Source/WebKit/UIProcess/WebProcessCache.h
r241635 r241855 42 42 explicit WebProcessCache(WebProcessPool&); 43 43 44 bool addProcess (const String& registrableDomain, Ref<WebProcessProxy>&&);44 bool addProcessIfPossible(const String& registrableDomain, Ref<WebProcessProxy>&&); 45 45 RefPtr<WebProcessProxy> takeProcess(const String& registrableDomain, WebsiteDataStore&); 46 46 … … 59 59 void evictProcess(WebProcessProxy&); 60 60 void platformInitialize(); 61 bool addProcess(const String& registrableDomain, Ref<WebProcessProxy>&&); 61 62 62 63 unsigned m_capacity { 0 }; -
trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp
r241778 r241855 637 637 auto provisionalPages = WTF::map(m_provisionalPages, [](auto* provisionalPage) { return makeWeakPtr(provisionalPage); }); 638 638 639 auto isResponsiveCallbacks = WTFMove(m_isResponsiveCallbacks); 640 for (auto& callback : isResponsiveCallbacks) 641 callback(false); 642 639 643 if (m_isInProcessCache) { 640 644 auto removedProcess = processPool().webProcessCache().takeProcess(registrableDomain(), websiteDataStore()); … … 840 844 return; 841 845 842 if (canBeAddedToWebProcessCache() && processPool().webProcessCache().addProcess (registrableDomain(), *this))846 if (canBeAddedToWebProcessCache() && processPool().webProcessCache().addProcessIfPossible(registrableDomain(), *this)) 843 847 return; 844 848 … … 1184 1188 } 1185 1189 1186 void WebProcessProxy::isResponsive( WTF::Function<void(bool isWebProcessResponsive)>&& callback)1190 void WebProcessProxy::isResponsive(CompletionHandler<void(bool isWebProcessResponsive)>&& callback) 1187 1191 { 1188 1192 if (m_isResponsive == NoOrMaybe::No) { 1189 1193 if (callback) { 1190 RunLoop::main().dispatch([callback = WTFMove(callback)] {1194 RunLoop::main().dispatch([callback = WTFMove(callback)]() mutable { 1191 1195 bool isWebProcessResponsive = false; 1192 1196 callback(isWebProcessResponsive); -
trunk/Source/WebKit/UIProcess/WebProcessProxy.h
r241778 r241855 207 207 ProcessThrottler& throttler() { return m_throttler; } 208 208 209 void isResponsive( WTF::Function<void(bool isWebProcessResponsive)>&&);209 void isResponsive(CompletionHandler<void(bool isWebProcessResponsive)>&&); 210 210 void isResponsiveWithLazyStop(); 211 211 void didReceiveMainThreadPing(); … … 410 410 411 411 enum class NoOrMaybe { No, Maybe } m_isResponsive; 412 Vector< WTF::Function<void(bool webProcessIsResponsive)>> m_isResponsiveCallbacks;412 Vector<CompletionHandler<void(bool webProcessIsResponsive)>> m_isResponsiveCallbacks; 413 413 414 414 VisibleWebPageCounter m_visiblePageCounter;
Note: See TracChangeset
for help on using the changeset viewer.