Changeset 244091 in webkit
- Timestamp:
- Apr 9, 2019, 12:37:28 PM (6 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 1 added
- 15 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r244089 r244091 1 2019-04-09 Jer Noble <jer.noble@apple.com> 2 3 [Cocoa] Awaken UIProcess if WebContent process is awakened from suspensions unexpectedly. 4 https://bugs.webkit.org/show_bug.cgi?id=196659 5 6 Reviewed by Chris Dumez. 7 8 * Platform/IPC/Connection.h: 9 (IPC::Connection::sendWithAsyncReply): 10 * Platform/spi/ios/AssertionServicesSPI.h: 11 * Shared/Cocoa/ProcessTaskStateObserver.h: Added. 12 (WebKit::ProcessTaskStateObserver::setClient): 13 (WebKit::ProcessTaskStateObserver::client): 14 (WebKit::ProcessTaskStateObserver::taskState const): 15 * Shared/Cocoa/ProcessTaskStateObserver.mm: Added. 16 (-[WKProcessTaskStateObserverDelegate process:taskStateDidChange:]): 17 (WebKit::toProcessTaskStateObserverTaskState): 18 (WebKit::ProcessTaskStateObserver::ProcessTaskStateObserver): 19 (WebKit::ProcessTaskStateObserver::~ProcessTaskStateObserver): 20 (WebKit::ProcessTaskStateObserver::setTaskState): 21 * UIProcess/Cocoa/WebProcessProxyCocoa.mm: 22 (WebKit::WebProcessProxy::processWasUnexpectedlyUnsuspended): 23 * UIProcess/ProcessAssertion.h: 24 * UIProcess/ProcessThrottler.cpp: 25 (WebKit::ProcessThrottler::updateAssertion): 26 * UIProcess/ProcessThrottler.h: 27 (WebKit::ProcessThrottler::shouldBeRunnable const): 28 * UIProcess/WebProcessProxy.h: 29 * UIProcess/WebProcessProxy.messages.in: 30 * UIProcess/ios/ProcessAssertionIOS.mm: 31 (WebKit::reasonForState): 32 (WebKit::toBKSProcessAssertionReason): 33 (WebKit::ProcessAssertion::ProcessAssertion): 34 * WebKit.xcodeproj/project.pbxproj: 35 * WebProcess/WebProcess.cpp: 36 (WebKit::WebProcess::actualPrepareToSuspend): 37 (WebKit::WebProcess::cancelPrepareToSuspend): 38 (WebKit::WebProcess::processDidResume): 39 * WebProcess/WebProcess.h: 40 * WebProcess/cocoa/WebProcessCocoa.mm: 41 (WebKit::WebProcess::processTaskStateDidChange): 42 1 43 2019-04-09 Alex Christensen <achristensen@webkit.org> 2 44 -
trunk/Source/WebKit/Platform/IPC/Connection.h
r243460 r244091 178 178 void postConnectionDidCloseOnConnectionWorkQueue(); 179 179 180 template<typename T, typename ... Args> void sendWithAsyncReply(T&& message, CompletionHandler<void(Args...)>&& args, uint64_t destinationID = 0);180 template<typename T, typename C> void sendWithAsyncReply(T&& message, C&& completionHandler, uint64_t destinationID = 0); 181 181 template<typename T> bool send(T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions = { }); 182 182 template<typename T> void sendWithReply(T&& message, uint64_t destinationID, FunctionDispatcher& replyDispatcher, Function<void(Optional<typename CodingType<typename T::Reply>::Type>)>&& replyHandler); … … 417 417 CompletionHandler<void(Decoder*)> takeAsyncReplyHandler(Connection&, uint64_t); 418 418 419 template<typename T, typename ... Args>420 void Connection::sendWithAsyncReply(T&& message, C ompletionHandler<void(Args...)>&& completionHandler, uint64_t destinationID)419 template<typename T, typename C> 420 void Connection::sendWithAsyncReply(T&& message, C&& completionHandler, uint64_t destinationID) 421 421 { 422 422 COMPILE_ASSERT(!T::isSync, AsyncMessageExpected); -
trunk/Source/WebKit/Platform/spi/ios/AssertionServicesSPI.h
r240954 r244091 29 29 30 30 #import <AssertionServices/BKSApplicationStateMonitor.h> 31 #import <AssertionServices/BKSProcess.h> 31 32 #import <AssertionServices/BKSProcessAssertion.h> 32 33 … … 69 70 70 71 enum { 72 BKSProcessAssertionReasonFinishTask = 4, 71 73 BKSProcessAssertionReasonExtension = 13, 72 74 BKSProcessAssertionReasonFinishTaskUnbounded = 10004, … … 88 90 @end 89 91 92 enum { 93 BKSProcessTaskStateNone, 94 BKSProcessTaskStateRunning, 95 BKSProcessTaskStateSuspended, 96 }; 97 typedef uint32_t BKSProcessTaskState; 98 99 @class BKSProcess; 100 101 @protocol BKSProcessDelegate <NSObject> 102 @optional 103 - (void)process:(BKSProcess *)process taskStateDidChange:(BKSProcessTaskState)newState; 104 @end 105 106 @interface BKSProcess : NSObject 107 @end 108 109 @interface BKSProcess () 110 + (BKSProcess *)currentProcess; 111 @property (nonatomic, readwrite, weak) id <BKSProcessDelegate> delegate; 112 @property (nonatomic, readonly, assign) BKSProcessTaskState taskState; 113 @end 114 90 115 #endif -
trunk/Source/WebKit/Shared/Cocoa/ProcessTaskStateObserver.h
r244090 r244091 1 1 /* 2 * Copyright (C) 201 4-2019 Apple Inc. All rights reserved.2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #include "config.h" 27 #include "ProcessAssertion.h" 26 #pragma once 28 27 29 #if !PLATFORM(IOS_FAMILY) 28 #if PLATFORM(IOS_FAMILY) 29 30 #include <wtf/RetainPtr.h> 31 32 OBJC_CLASS WKProcessTaskStateObserverDelegate; 33 OBJC_CLASS BKSProcess; 30 34 31 35 namespace WebKit { 32 36 33 ProcessAssertion::ProcessAssertion(ProcessID, const String&, AssertionState assertionState) 34 : m_assertionState(assertionState) 35 { 37 class ProcessTaskStateObserver { 38 public: 39 class Client; 40 41 ProcessTaskStateObserver(); 42 explicit ProcessTaskStateObserver(Client&); 43 ~ProcessTaskStateObserver(); 44 45 enum TaskState { 46 None, 47 Running, 48 Suspended, 49 }; 50 51 class Client { 52 public: 53 virtual ~Client() = default; 54 virtual void processTaskStateDidChange(TaskState) = 0; 55 }; 56 57 void setClient(Client& client) { m_client = &client; } 58 Client* client() { return m_client; } 59 60 TaskState taskState() const { return m_taskState; } 61 62 private: 63 void setTaskState(TaskState); 64 65 Client* m_client { nullptr }; 66 TaskState m_taskState { None }; 67 RetainPtr<BKSProcess> m_process; 68 RetainPtr<WKProcessTaskStateObserverDelegate> m_delegate; 69 }; 70 36 71 } 37 72 38 ProcessAssertion::~ProcessAssertion() = default; 39 40 void ProcessAssertion::setState(AssertionState assertionState) 41 { 42 m_assertionState = assertionState; 43 } 44 45 } // namespace WebKit 46 47 #endif // !PLATFORM(IOS_FAMILY) 73 #endif // PLATFORM(IOS_FAMILY) -
trunk/Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm
r242339 r244091 42 42 namespace WebKit { 43 43 44 static const Seconds unexpectedActivityDuration = 10_s; 45 44 46 const HashSet<String>& WebProcessProxy::platformPathsWithAssumedReadAccess() 45 47 { … … 188 190 #endif 189 191 190 } 192 #if PLATFORM(IOS_FAMILY) 193 void WebProcessProxy::processWasUnexpectedlyUnsuspended(CompletionHandler<void()>&& completion) 194 { 195 if (m_throttler.shouldBeRunnable()) { 196 // The process becoming unsuspended was not unexpected; it likely was notified of its running state 197 // before receiving a procsessDidResume() message from the UIProcess. 198 completion(); 199 return; 200 } 201 202 // The WebProcess was awakened by something other than the UIProcess. Take out an assertion for a 203 // limited duration to allow whatever task needs to be accomplished time to complete. 204 RELEASE_LOG(ProcessSuspension, "%p - WebProcessProxy::processWasUnexpectedlyUnsuspended()", this); 205 auto backgroundActivityTimeoutHandler = [activityToken = m_throttler.backgroundActivityToken(), weakThis = makeWeakPtr(this)] { 206 RELEASE_LOG(ProcessSuspension, "%p - WebProcessProxy::processWasUnexpectedlyUnsuspended() - lambda, background activity timed out", weakThis.get()); 207 }; 208 m_unexpectedActivityTimer = std::make_unique<WebCore::DeferrableOneShotTimer>(WTFMove(backgroundActivityTimeoutHandler), unexpectedActivityDuration); 209 completion(); 210 } 211 #endif 212 213 } -
trunk/Source/WebKit/UIProcess/ProcessAssertion.cpp
r242666 r244091 36 36 } 37 37 38 ProcessAssertion::ProcessAssertion(pid_t pid, const String& name, AssertionState assertionState, AssertionReason) 39 : m_assertionState(assertionState) 40 { 41 } 42 38 43 ProcessAssertion::~ProcessAssertion() = default; 39 44 -
trunk/Source/WebKit/UIProcess/ProcessAssertion.h
r242666 r244091 46 46 Background, 47 47 UnboundedNetworking, 48 Foreground 48 Foreground, 49 }; 50 51 enum class AssertionReason { 52 Extension, 53 FinishTask, 54 FinishTaskUnbounded, 49 55 }; 50 56 … … 59 65 60 66 ProcessAssertion(ProcessID, const String& reason, AssertionState); 67 ProcessAssertion(ProcessID, const String& reason, AssertionState, AssertionReason); 61 68 virtual ~ProcessAssertion(); 62 69 -
trunk/Source/WebKit/UIProcess/ProcessThrottler.cpp
r242610 r244091 69 69 void ProcessThrottler::updateAssertion() 70 70 { 71 bool shouldBeRunnable = m_foregroundCounter.value() || m_backgroundCounter.value();71 bool shouldBeRunnable = this->shouldBeRunnable(); 72 72 73 73 // If the process is currently runnable but will be suspended then first give it a chance to complete what it was doing -
trunk/Source/WebKit/UIProcess/ProcessThrottler.h
r242610 r244091 61 61 void processReadyToSuspend(); 62 62 void didCancelProcessSuspension(); 63 bool shouldBeRunnable() const { return m_foregroundCounter.value() || m_backgroundCounter.value(); } 63 64 64 65 private: -
trunk/Source/WebKit/UIProcess/WebProcessProxy.h
r244085 r244091 58 58 59 59 namespace WebCore { 60 class DeferrableOneShotTimer; 60 61 class ResourceRequest; 61 62 struct PluginInfo; … … 302 303 #endif 303 304 305 #if PLATFORM(IOS_FAMILY) 306 void processWasUnexpectedlyUnsuspended(CompletionHandler<void()>&&); 307 #endif 308 304 309 protected: 305 310 static uint64_t generatePageID(); … … 449 454 BackgroundWebProcessToken m_backgroundToken; 450 455 bool m_hasSentMessageToUnblockAccessibilityServer { false }; 456 std::unique_ptr<WebCore::DeferrableOneShotTimer> m_unexpectedActivityTimer; 451 457 #endif 452 458 -
trunk/Source/WebKit/UIProcess/WebProcessProxy.messages.in
r244085 r244091 84 84 DidCreateContextForVisibilityPropagation(WebKit::LayerHostingContextID contextID); 85 85 #endif 86 87 #if PLATFORM(IOS_FAMILY) 88 ProcessWasUnexpectedlyUnsuspended() -> () Async 89 #endif 86 90 } -
trunk/Source/WebKit/UIProcess/ios/ProcessAssertionIOS.mm
r242728 r244091 147 147 } 148 148 149 static BKSProcessAssertionReason reasonForState(AssertionState assertionState)149 static AssertionReason reasonForState(AssertionState assertionState) 150 150 { 151 151 switch (assertionState) { 152 152 case AssertionState::UnboundedNetworking: 153 return BKSProcessAssertionReasonFinishTaskUnbounded;153 return AssertionReason::FinishTaskUnbounded; 154 154 case AssertionState::Suspended: 155 155 case AssertionState::Background: 156 156 case AssertionState::Foreground: 157 return AssertionReason::Extension; 158 } 159 } 160 161 static BKSProcessAssertionReason toBKSProcessAssertionReason(AssertionReason reason) 162 { 163 switch (reason) { 164 case AssertionReason::Extension: 157 165 return BKSProcessAssertionReasonExtension; 166 case AssertionReason::FinishTask: 167 return BKSProcessAssertionReasonFinishTask; 168 case AssertionReason::FinishTaskUnbounded: 169 return BKSProcessAssertionReasonFinishTaskUnbounded; 158 170 } 159 171 } 160 172 161 173 ProcessAssertion::ProcessAssertion(pid_t pid, const String& name, AssertionState assertionState) 174 : ProcessAssertion(pid, name, assertionState, reasonForState(assertionState)) 175 { 176 } 177 178 ProcessAssertion::ProcessAssertion(pid_t pid, const String& name, AssertionState assertionState, AssertionReason assertionReason) 162 179 : m_assertionState(assertionState) 163 180 { … … 174 191 RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion() PID %d acquiring assertion for process with PID %d, name '%s'", this, getpid(), pid, name.utf8().data()); 175 192 176 m_assertion = adoptNS([[BKSProcessAssertion alloc] initWithPID:pid flags:flagsForState(assertionState) reason: reasonForState(assertionState) name:(NSString *)name withHandler:handler]);193 m_assertion = adoptNS([[BKSProcessAssertion alloc] initWithPID:pid flags:flagsForState(assertionState) reason:toBKSProcessAssertionReason(assertionReason) name:(NSString *)name withHandler:handler]); 177 194 m_assertion.get().invalidationHandler = ^() { 178 195 dispatch_async(dispatch_get_main_queue(), ^{ -
trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj
r243932 r244091 1562 1562 CD19A26E1A13E834008D650E /* WebDiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CD19A26A1A13E821008D650E /* WebDiagnosticLoggingClient.h */; }; 1563 1563 CD19D2EA2046406F0017074A /* FullscreenTouchSecheuristic.h in Headers */ = {isa = PBXBuildFile; fileRef = CD19D2E82046406F0017074A /* FullscreenTouchSecheuristic.h */; }; 1564 CD2865EE2255562000606AC7 /* ProcessTaskStateObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = CD2865EC2255562000606AC7 /* ProcessTaskStateObserver.h */; }; 1565 CD2865EF2255562000606AC7 /* ProcessTaskStateObserver.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD2865ED2255562000606AC7 /* ProcessTaskStateObserver.mm */; }; 1564 1566 CD491B081E70D05F00009066 /* UserMediaCaptureManager.h in Headers */ = {isa = PBXBuildFile; fileRef = CD491B061E70D05F00009066 /* UserMediaCaptureManager.h */; }; 1565 1567 CD491B0D1E732E4D00009066 /* UserMediaCaptureManagerMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD491B0B1E732E4D00009066 /* UserMediaCaptureManagerMessageReceiver.cpp */; }; … … 4418 4420 CD19D2E82046406F0017074A /* FullscreenTouchSecheuristic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FullscreenTouchSecheuristic.h; path = ios/fullscreen/FullscreenTouchSecheuristic.h; sourceTree = "<group>"; }; 4419 4421 CD19D2E92046406F0017074A /* FullscreenTouchSecheuristic.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FullscreenTouchSecheuristic.cpp; path = ios/fullscreen/FullscreenTouchSecheuristic.cpp; sourceTree = "<group>"; }; 4422 CD2865EC2255562000606AC7 /* ProcessTaskStateObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProcessTaskStateObserver.h; sourceTree = "<group>"; }; 4423 CD2865ED2255562000606AC7 /* ProcessTaskStateObserver.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ProcessTaskStateObserver.mm; sourceTree = "<group>"; }; 4420 4424 CD491B051E70D05F00009066 /* UserMediaCaptureManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMediaCaptureManager.cpp; sourceTree = "<group>"; }; 4421 4425 CD491B061E70D05F00009066 /* UserMediaCaptureManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMediaCaptureManager.h; sourceTree = "<group>"; }; … … 6314 6318 C55F916D1C595E440029E92D /* DataDetectionResult.mm */, 6315 6319 2D1087621D2C641B00B85F82 /* LoadParametersCocoa.mm */, 6320 CD2865EC2255562000606AC7 /* ProcessTaskStateObserver.h */, 6321 CD2865ED2255562000606AC7 /* ProcessTaskStateObserver.mm */, 6316 6322 CD4B4D9A1E765E0000D27092 /* SharedRingBufferStorage.cpp */, 6317 6323 CD4B4D9B1E765E0000D27092 /* SharedRingBufferStorage.h */, … … 9398 9404 86F9536518FF58F5001DB2EF /* ProcessAssertion.h in Headers */, 9399 9405 BC1A7C581136E19C00FB7167 /* ProcessLauncher.h in Headers */, 9406 CD2865EE2255562000606AC7 /* ProcessTaskStateObserver.h in Headers */, 9400 9407 463FD4821EB94EC000A2982C /* ProcessTerminationReason.h in Headers */, 9401 9408 86E67A251910B9D100004AB7 /* ProcessThrottler.h in Headers */, … … 10973 10980 2D91344D212CF9F000128AFD /* PluginView.cpp in Sources */, 10974 10981 2D54C31B212F4DA60049C174 /* ProcessLauncher.cpp in Sources */, 10982 CD2865EF2255562000606AC7 /* ProcessTaskStateObserver.mm in Sources */, 10975 10983 2D72A1FA212BF46E00517A20 /* RemoteLayerTreeDrawingArea.mm in Sources */, 10976 10984 0FF24A2D1879E4BC003ABF0C /* RemoteLayerTreeDrawingAreaProxyMessageReceiver.cpp in Sources */, -
trunk/Source/WebKit/WebProcess/WebProcess.cpp
r243958 r244091 1451 1451 { 1452 1452 SetForScope<bool> suspensionScope(m_isSuspending, true); 1453 m_processIsSuspended = true; 1453 1454 1454 1455 #if ENABLE(VIDEO) … … 1512 1513 { 1513 1514 RELEASE_LOG(ProcessSuspension, "%p - WebProcess::cancelPrepareToSuspend()", this); 1515 1516 m_processIsSuspended = false; 1517 1514 1518 unfreezeAllLayerTrees(); 1515 1519 … … 1585 1589 RELEASE_LOG(ProcessSuspension, "%p - WebProcess::processDidResume()", this); 1586 1590 1591 m_processIsSuspended = false; 1592 1587 1593 cancelMarkAllLayersVolatile(); 1588 1594 unfreezeAllLayerTrees(); -
trunk/Source/WebKit/WebProcess/WebProcess.h
r244085 r244091 56 56 #include <dispatch/dispatch.h> 57 57 #include <wtf/MachSendRight.h> 58 #endif 59 60 #if PLATFORM(IOS_FAMILY) 61 #include "ProcessTaskStateObserver.h" 58 62 #endif 59 63 … … 117 121 #endif 118 122 119 class WebProcess : public AuxiliaryProcess { 123 class WebProcess 124 : public AuxiliaryProcess 125 #if PLATFORM(IOS_FAMILY) 126 , ProcessTaskStateObserver::Client 127 #endif 128 { 120 129 public: 121 130 static WebProcess& singleton(); … … 430 439 431 440 #if PLATFORM(IOS_FAMILY) 441 void processTaskStateDidChange(ProcessTaskStateObserver::TaskState) final; 432 442 bool shouldFreezeOnSuspension() const; 433 443 void updateFreezerStatus(); … … 495 505 #endif 496 506 507 bool m_processIsSuspended { false }; 508 497 509 HashSet<uint64_t> m_pagesInWindows; 498 510 WebCore::Timer m_nonVisibleProcessCleanupTimer; … … 502 514 #if PLATFORM(IOS_FAMILY) 503 515 std::unique_ptr<WebSQLiteDatabaseTracker> m_webSQLiteDatabaseTracker; 516 ProcessTaskStateObserver m_taskStateObserver { *this }; 504 517 #endif 505 518 #if HAVE(VISIBILITY_PROPAGATION_VIEW) -
trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm
r244085 r244091 32 32 #import "Logging.h" 33 33 #import "ObjCObjectGraph.h" 34 #import "ProcessAssertion.h" 34 35 #import "SandboxExtension.h" 35 36 #import "SandboxInitializationParameters.h" … … 288 289 } 289 290 291 #if PLATFORM(IOS_FAMILY) 292 void WebProcess::processTaskStateDidChange(ProcessTaskStateObserver::TaskState taskState) 293 { 294 RELEASE_LOG(ProcessSuspension, "%p - WebProcess::processTaskStateDidChange() - taskState(%d)", this, taskState); 295 if (taskState == ProcessTaskStateObserver::None) 296 return; 297 298 if (taskState == ProcessTaskStateObserver::Suspended) { 299 if (m_processIsSuspended) 300 return; 301 302 RELEASE_LOG(ProcessSuspension, "%p - WebProcess::processTaskStateChanged() - unexpectedly entered Suspended state", this); 303 return; 304 } 305 306 if (!m_processIsSuspended) 307 return; 308 309 // We were awakened from suspension unexpectedly. Notify the WebProcessProxy, but take a process assertion on our parent PID 310 // to ensure that it too is awakened. 311 auto uiProcessAssertion = std::make_unique<ProcessAssertion>(parentProcessConnection()->remoteProcessID(), "Unexpectedly resumed", AssertionState::Background, AssertionReason::FinishTask); 312 parentProcessConnection()->sendWithAsyncReply(Messages::WebProcessProxy::ProcessWasUnexpectedlyUnsuspended(), [uiProcessAssertion = WTFMove(uiProcessAssertion)] { }); 313 } 314 #endif 315 290 316 static void registerWithAccessibility() 291 317 {
Note:
See TracChangeset
for help on using the changeset viewer.