Changeset 249703 in webkit
- Timestamp:
- Sep 9, 2019 9:24:23 PM (5 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r249702 r249703 1 2019-09-09 Chris Dumez <cdumez@apple.com> 2 3 [iOS] We sometimes attempt to use a terminated prewarmed WebContent process 4 https://bugs.webkit.org/show_bug.cgi?id=201614 5 <rdar://problem/54714507> 6 7 Reviewed by Geoffrey Garen. 8 9 On iOS, it is possible for our processes to get terminated (e.g. jetsammed) while the UIProcess 10 is suspended. Upon resuming, it takes a little while for the UIProcess to get the notification 11 that the mac connection to its child process has been severed and the UIProcess may try to use 12 it for a load. This is especially problematic for prewarmed process because the client will end 13 up showing a crash banner and reloading when we could have used a new process rather the prewarmed 14 one if we had known it was dead. 15 16 This patch makes 2 improvements: 17 1. It makes AuxiliaryProcessProxy::state() return Terminated if we still have a connection but 18 the PID is not the PID of a running process. I also added a check in tryTakePrewarmedProcess() 19 to not use the prewarmed process if it state() is Terminated. 20 2. When the UIProcess is about to get suspended, have the process pools terminate their non-critical 21 processes (i.e. prewarmed + the ones used for PageCache). This makes WebKit friendlier with 22 other apps on the system when suspended with regards to memory. Also, it makes it less likely 23 useful WebContent processes will get jetsammed. 24 25 * UIProcess/AuxiliaryProcessProxy.cpp: 26 (WebKit::AuxiliaryProcessProxy::state const): 27 (WebKit::AuxiliaryProcessProxy::isRunningProcessPID): 28 * UIProcess/AuxiliaryProcessProxy.h: 29 * UIProcess/Cocoa/WebProcessPoolCocoa.mm: 30 (WebKit::WebProcessPool::applicationIsAboutToSuspend): 31 * UIProcess/WebProcessPool.cpp: 32 (WebKit::WebProcessPool::tryTakePrewarmedProcess): 33 * UIProcess/WebProcessPool.h: 34 * UIProcess/ios/ProcessAssertionIOS.mm: 35 (-[WKProcessAssertionBackgroundTaskManager init]): 36 (-[WKProcessAssertionBackgroundTaskManager _releaseBackgroundTask]): 37 1 38 2019-09-09 Chris Dumez <cdumez@apple.com> 2 39 -
trunk/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp
r249649 r249703 29 29 #include "AuxiliaryProcessMessages.h" 30 30 #include "LoadParameters.h" 31 #include "Logging.h" 31 32 #include "WebPageMessages.h" 32 33 #include <wtf/RunLoop.h> … … 109 110 return AuxiliaryProcessProxy::State::Launching; 110 111 111 if (!m_connection) 112 // There is sometimes a delay until we get the notification from mach about the connection getting closed. 113 // To help detect terminated process earlier, we also check that the PID is for a valid running process. 114 if (!m_connection || !isRunningProcessPID(processIdentifier())) 112 115 return AuxiliaryProcessProxy::State::Terminated; 113 116 114 117 return AuxiliaryProcessProxy::State::Running; 118 } 119 120 bool AuxiliaryProcessProxy::isRunningProcessPID(ProcessID pid) 121 { 122 if (!pid) 123 return false; 124 125 #if PLATFORM(COCOA) 126 // Use kill() with a signal of 0 to check if there is actually still a process with the given PID. 127 if (!kill(pid, 0)) 128 return true; 129 130 if (errno == ESRCH) { 131 // No process can be found corresponding to that specified by pid. 132 return false; 133 } 134 135 RELEASE_LOG_ERROR(Process, "kill() returned unexpected error %d", errno); 136 return true; 137 #else 138 UNUSED_PARAM(pid); 139 return true; 140 #endif 115 141 } 116 142 -
trunk/Source/WebKit/UIProcess/AuxiliaryProcessProxy.h
r248846 r249703 124 124 virtual void connectionWillOpen(IPC::Connection&); 125 125 virtual void processWillShutDown(IPC::Connection&) = 0; 126 static bool isRunningProcessPID(ProcessID); 126 127 127 128 Vector<std::pair<std::unique_ptr<IPC::Encoder>, OptionSet<IPC::SendOption>>> m_pendingMessages; -
trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
r249684 r249703 30 30 #import "CookieStorageUtilsCF.h" 31 31 #import "LegacyCustomProtocolManagerClient.h" 32 #import "Logging.h" 32 33 #import "NetworkProcessCreationParameters.h" 33 34 #import "NetworkProcessMessages.h" … … 581 582 } 582 583 584 #if PLATFORM(IOS_FAMILY) 585 void WebProcessPool::applicationIsAboutToSuspend() 586 { 587 RELEASE_LOG(ProcessSuspension, "Application is about to suspend so we simulate memory pressure to terminate non-critical processes"); 588 // Simulate memory pressure handling so free as much memory as possible before suspending. 589 // In particular, this will terminate prewarmed and PageCache processes. 590 for (auto* processPool : allProcessPools()) 591 processPool->handleMemoryPressureWarning(Critical::Yes); 592 } 593 #endif 594 583 595 } // namespace WebKit -
trunk/Source/WebKit/UIProcess/WebProcessPool.cpp
r249671 r249703 826 826 if (!m_prewarmedProcess) 827 827 return nullptr; 828 829 // There is sometimes a delay until we get notified that a prewarmed process has been terminated (e.g. after resuming 830 // from suspension) so make sure the process is still running here before deciding to use it. 831 if (m_prewarmedProcess->state() == AuxiliaryProcessProxy::State::Terminated) { 832 RELEASE_LOG_ERROR(Process, "Not using prewarmed process %d because it has been terminated", m_prewarmedProcess->processIdentifier()); 833 m_prewarmedProcess = nullptr; 834 return nullptr; 835 } 828 836 829 837 #if PLATFORM(GTK) || PLATFORM(WPE) -
trunk/Source/WebKit/UIProcess/WebProcessPool.h
r249671 r249703 223 223 void populateVisitedLinks(); 224 224 225 #if PLATFORM(IOS_FAMILY) 226 static void applicationIsAboutToSuspend(); 227 #endif 228 225 229 void handleMemoryPressureWarning(Critical); 226 230 -
trunk/Source/WebKit/UIProcess/ios/ProcessAssertionIOS.mm
r247109 r249703 31 31 #import "AssertionServicesSPI.h" 32 32 #import "Logging.h" 33 #import "WebProcessPool.h" 33 34 #import <UIKit/UIApplication.h> 34 35 #import <wtf/HashMap.h> … … 82 83 [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:[UIApplication sharedApplication] queue:nil usingBlock:^(NSNotification *) { 83 84 _applicationIsBackgrounded = YES; 85 86 if (_backgroundTask == UIBackgroundTaskInvalid) 87 WebKit::WebProcessPool::applicationIsAboutToSuspend(); 84 88 }]; 85 89 … … 184 188 185 189 RELEASE_LOG(ProcessSuspension, "%p - WKProcessAssertionBackgroundTaskManager - endBackgroundTask", self); 190 if (_applicationIsBackgrounded) 191 WebKit::WebProcessPool::applicationIsAboutToSuspend(); 186 192 [[UIApplication sharedApplication] endBackgroundTask:_backgroundTask]; 187 193 _backgroundTask = UIBackgroundTaskInvalid;
Note: See TracChangeset
for help on using the changeset viewer.