Changeset 236512 in webkit
- Timestamp:
- Sep 26, 2018, 11:38:26 AM (8 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 7 edited
-
ChangeLog (modified) (1 diff)
-
UIProcess/WebPageProxy.cpp (modified) (8 diffs)
-
UIProcess/WebPageProxy.h (modified) (1 diff)
-
UIProcess/WebPageProxy.messages.in (modified) (1 diff)
-
WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (modified) (1 diff)
-
WebProcess/WebPage/WebFrame.cpp (modified) (2 diffs)
-
WebProcess/WebProcess.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r236500 r236512 1 2018-09-26 Chris Dumez <cdumez@apple.com> 2 3 UIProcess should process incoming sync IPC from WebProcess when waiting for a sync IPC reply from it 4 https://bugs.webkit.org/show_bug.cgi?id=189927 5 6 Reviewed by Geoffrey Garen. 7 8 UIProcess should process incoming sync IPC from WebProcess when waiting for a sync IPC reply from it 9 in order to avoid deadlocks. This is not an issue currently because the WebProcess does process 10 incoming sync IPC when waiting for a sync IPC reply. However, we plan to change this in the future 11 in order to avoid bugs caused by re-entering WebCore at unsafe times. 12 13 The reason the UIProcess previously did not do out of order sync IPC process was to avoid processing 14 a synchronous policy decision IPC for a frameID it did not know about yet, due to the DidCreateMainFrame / 15 DidCreateSubframe IPC messages being asynchronous. To address this issue, the decidePolicyForNavigationActionSync 16 IPC handler now calls didCreateMainFrame() / didCreateSubframe() as needed if it does not know about 17 the frame yet. Note that synchronous policy decisions are rare and are currently only needed by initial 18 about:blank and fragment navigations. 19 20 * UIProcess/WebPageProxy.cpp: 21 (WebKit::WebPageProxy::didCreateMainFrame): 22 (WebKit::WebPageProxy::didCreateSubframe): 23 (WebKit::WebPageProxy::decidePolicyForNavigationActionAsync): 24 (WebKit::WebPageProxy::decidePolicyForNavigationAction): 25 (WebKit::WebPageProxy::decidePolicyForNavigationActionSync): 26 * UIProcess/WebPageProxy.h: 27 * UIProcess/WebPageProxy.messages.in: 28 * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: 29 (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction): 30 31 * WebProcess/WebPage/WebFrame.cpp: 32 (WebKit::WebFrame::createWithCoreMainFrame): 33 (WebKit::WebFrame::createSubframe): 34 Drop DispatchMessageEvenWhenWaitingForSyncReply SendOption when sending the 35 DidCreateMainFrame / DidCreateSubframe IPC. Previously, this SendOption has 36 no effect because the IPC::Connection would have the 37 m_onlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage 38 flag set to true. However, now that we stop setting this flag on the IPC 39 connection from the WebProcess to the UIProcess, it would lead to those 40 IPC messages getting processed out of order with regards to the 41 DecidePolicyForNavigationAsync asynchronous IPC. DidCreateMainFrame would 42 sometimes get processed *after* the DecidePolicyForNavigationAsync IPC 43 and we would not know about the frameID yet. 44 45 * WebProcess/WebProcess.cpp: 46 (WebKit::WebProcess::initializeConnection): 47 1 48 2018-09-26 Antti Koivisto <antti@apple.com> 2 49 -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r236500 r236512 3358 3358 void WebPageProxy::didCreateMainFrame(uint64_t frameID) 3359 3359 { 3360 if (m_mainFrame && m_mainFrame->frameID() == frameID) 3361 return; 3362 3360 3363 PageClientProtector protector(pageClient()); 3361 3364 … … 3380 3383 3381 3384 MESSAGE_CHECK(m_mainFrame); 3385 3386 if (m_process->webFrame(frameID)) 3387 return; 3388 3382 3389 MESSAGE_CHECK(m_process->canCreateFrame(frameID)); 3383 3390 … … 3997 4004 void WebPageProxy::decidePolicyForNavigationActionAsync(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&& navigationActionData, const FrameInfoData& frameInfoData, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&& request, WebCore::ResourceResponse&& redirectResponse, const UserData& userData, WebCore::ShouldSkipSafeBrowsingCheck shouldSkipSafeBrowsingCheck, uint64_t listenerID) 3998 4005 { 3999 decidePolicyForNavigationAction(frameID, frameSecurityOrigin, navigationID, WTFMove(navigationActionData), frameInfoData, originatingPageID, originalRequest, WTFMove(request), WTFMove(redirectResponse), userData, shouldSkipSafeBrowsingCheck, PolicyDecisionSender::create([this, protectedThis = makeRef(*this), frameID, listenerID] (auto... args) { 4006 auto* frame = m_process->webFrame(frameID); 4007 MESSAGE_CHECK(frame); 4008 4009 decidePolicyForNavigationAction(*frame, frameSecurityOrigin, navigationID, WTFMove(navigationActionData), frameInfoData, originatingPageID, originalRequest, WTFMove(request), WTFMove(redirectResponse), userData, shouldSkipSafeBrowsingCheck, PolicyDecisionSender::create([this, protectedThis = makeRef(*this), frameID, listenerID] (auto... args) { 4000 4010 m_process->send(Messages::WebPage::DidReceivePolicyDecision(frameID, listenerID, args...), m_pageID); 4001 4011 })); 4002 4012 } 4003 4013 4004 void WebPageProxy::decidePolicyForNavigationAction( uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&& navigationActionData, const FrameInfoData& originatingFrameInfoData, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&& request, WebCore::ResourceResponse&& redirectResponse, const UserData& userData, WebCore::ShouldSkipSafeBrowsingCheck shouldSkipSafeBrowsingCheck, Ref<PolicyDecisionSender>&& sender)4014 void WebPageProxy::decidePolicyForNavigationAction(WebFrameProxy& frame, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&& navigationActionData, const FrameInfoData& originatingFrameInfoData, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&& request, WebCore::ResourceResponse&& redirectResponse, const UserData& userData, WebCore::ShouldSkipSafeBrowsingCheck shouldSkipSafeBrowsingCheck, Ref<PolicyDecisionSender>&& sender) 4005 4015 { 4006 4016 LOG(Loading, "WebPageProxy::decidePolicyForNavigationAction - Original URL %s, current target URL %s", originalRequest.url().string().utf8().data(), request.url().string().utf8().data()); … … 4014 4024 m_pageLoadState.clearPendingAPIRequestURL(transaction); 4015 4025 4016 WebFrameProxy* frame = m_process->webFrame(frameID);4017 MESSAGE_CHECK(frame);4018 4026 MESSAGE_CHECK_URL(request.url()); 4019 4027 MESSAGE_CHECK_URL(originalRequest.url()); … … 4052 4060 4053 4061 #if ENABLE(CONTENT_FILTERING) 4054 if (frame ->didHandleContentFilterUnblockNavigation(request))4062 if (frame.didHandleContentFilterUnblockNavigation(request)) 4055 4063 return receivedPolicyDecision(PolicyAction::Ignore, m_navigationState->navigation(newNavigationID), std::nullopt, WTFMove(sender)); 4056 4064 #else … … 4058 4066 #endif 4059 4067 4060 auto listener = makeRef(frame ->setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), frame = makeRef(*frame), sender = WTFMove(sender), navigation] (WebCore::PolicyAction policyAction, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, Vector<Ref<SafeBrowsingResult>>&&) mutable {4068 auto listener = makeRef(frame.setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), frame = makeRef(frame), sender = WTFMove(sender), navigation] (WebCore::PolicyAction policyAction, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, Vector<Ref<SafeBrowsingResult>>&&) mutable { 4061 4069 // FIXME: do something with the SafeBrowsingResults. 4062 4070 receivedNavigationPolicyDecision(policyAction, navigation.get(), processSwapRequestedByClient, frame, policies, WTFMove(sender)); … … 4065 4073 beginSafeBrowsingCheck(request.url(), listener); 4066 4074 4067 API::Navigation* mainFrameNavigation = frame ->isMainFrame() ? navigation.get() : nullptr;4075 API::Navigation* mainFrameNavigation = frame.isMainFrame() ? navigation.get() : nullptr; 4068 4076 WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameInfoData.frameID); 4069 4077 4070 4078 if (auto* resourceLoadStatisticsStore = websiteDataStore().resourceLoadStatistics()) 4071 resourceLoadStatisticsStore->logFrameNavigation( *frame, URL(URL(), m_pageLoadState.url()), request, redirectResponse.url());4079 resourceLoadStatisticsStore->logFrameNavigation(frame, URL(URL(), m_pageLoadState.url()), request, redirectResponse.url()); 4072 4080 4073 4081 if (m_policyClient) 4074 m_policyClient->decidePolicyForNavigationAction(*this, frame, WTFMove(navigationActionData), originatingFrame, originalRequest, WTFMove(request), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());4082 m_policyClient->decidePolicyForNavigationAction(*this, &frame, WTFMove(navigationActionData), originatingFrame, originalRequest, WTFMove(request), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get()); 4075 4083 else { 4076 auto destinationFrameInfo = API::FrameInfo::create( *frame, frameSecurityOrigin.securityOrigin());4084 auto destinationFrameInfo = API::FrameInfo::create(frame, frameSecurityOrigin.securityOrigin()); 4077 4085 RefPtr<API::FrameInfo> sourceFrameInfo; 4078 if (!fromAPI && originatingFrame == frame)4086 if (!fromAPI && originatingFrame == &frame) 4079 4087 sourceFrameInfo = destinationFrameInfo.copyRef(); 4080 4088 else if (!fromAPI) … … 4092 4100 } 4093 4101 4094 void WebPageProxy::decidePolicyForNavigationActionSync(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&& navigationActionData, const FrameInfoData& frameInfoData, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&& request, WebCore::ResourceResponse&& redirectResponse, const UserData& userData, WebCore::ShouldSkipSafeBrowsingCheck shouldSkipSafeBrowsingCheck, Messages::WebPageProxy::DecidePolicyForNavigationActionSync::DelayedReply&& reply)4102 void WebPageProxy::decidePolicyForNavigationActionSync(uint64_t frameID, bool isMainFrame, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&& navigationActionData, const FrameInfoData& frameInfoData, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&& request, WebCore::ResourceResponse&& redirectResponse, const UserData& userData, WebCore::ShouldSkipSafeBrowsingCheck shouldSkipSafeBrowsingCheck, Messages::WebPageProxy::DecidePolicyForNavigationActionSync::DelayedReply&& reply) 4095 4103 { 4096 4104 auto sender = PolicyDecisionSender::create(WTFMove(reply)); 4105 4106 auto* frame = m_process->webFrame(frameID); 4107 if (!frame) { 4108 // This synchronous IPC message was processed before the asynchronous DidCreateMainFrame / DidCreateSubframe one so we do not know about this frameID yet. 4109 if (isMainFrame) 4110 didCreateMainFrame(frameID); 4111 else 4112 didCreateSubframe(frameID); 4113 4114 frame = m_process->webFrame(frameID); 4115 RELEASE_ASSERT(frame); 4116 } 4097 4117 4098 decidePolicyForNavigationAction( frameID, frameSecurityOrigin, navigationID, WTFMove(navigationActionData), frameInfoData, originatingPageID, originalRequest, WTFMove(request), WTFMove(redirectResponse), userData, shouldSkipSafeBrowsingCheck, sender.copyRef());4118 decidePolicyForNavigationAction(*frame, frameSecurityOrigin, navigationID, WTFMove(navigationActionData), frameInfoData, originatingPageID, originalRequest, WTFMove(request), WTFMove(redirectResponse), userData, shouldSkipSafeBrowsingCheck, sender.copyRef()); 4099 4119 4100 4120 // If the client did not respond synchronously, proceed with the load. -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r236500 r236512 1436 1436 void didDestroyNavigation(uint64_t navigationID); 1437 1437 1438 void decidePolicyForNavigationAction( uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&&, const FrameInfoData&, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&, WebCore::ResourceResponse&& redirectResponse, const UserData&, WebCore::ShouldSkipSafeBrowsingCheck, Ref<PolicyDecisionSender>&&);1438 void decidePolicyForNavigationAction(WebFrameProxy&, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&&, const FrameInfoData&, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&, WebCore::ResourceResponse&& redirectResponse, const UserData&, WebCore::ShouldSkipSafeBrowsingCheck, Ref<PolicyDecisionSender>&&); 1439 1439 void decidePolicyForNavigationActionAsync(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&&, const FrameInfoData&, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&, WebCore::ResourceResponse&& redirectResponse, const UserData&, WebCore::ShouldSkipSafeBrowsingCheck, uint64_t listenerID); 1440 void decidePolicyForNavigationActionSync(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&&, const FrameInfoData&, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&, WebCore::ResourceResponse&& redirectResponse, const UserData&, WebCore::ShouldSkipSafeBrowsingCheck, Messages::WebPageProxy::DecidePolicyForNavigationActionSync::DelayedReply&&);1440 void decidePolicyForNavigationActionSync(uint64_t frameID, bool isMainFrame, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&&, const FrameInfoData&, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&, WebCore::ResourceResponse&& redirectResponse, const UserData&, WebCore::ShouldSkipSafeBrowsingCheck, Messages::WebPageProxy::DecidePolicyForNavigationActionSync::DelayedReply&&); 1441 1441 void decidePolicyForNewWindowAction(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, NavigationActionData&&, WebCore::ResourceRequest&&, const String& frameName, uint64_t listenerID, const UserData&); 1442 1442 void decidePolicyForResponse(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&); -
trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in
r236485 r236512 109 109 DecidePolicyForResponse(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, WebCore::ResourceResponse response, WebCore::ResourceRequest request, bool canShowMIMEType, uint64_t listenerID, WebKit::UserData userData) 110 110 DecidePolicyForNavigationActionAsync(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, struct WebKit::FrameInfoData originatingFrameInfoData, uint64_t originatingPageID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, WebCore::ResourceResponse redirectResponse, WebKit::UserData userData, enum WebCore::ShouldSkipSafeBrowsingCheck shouldSkipSafeBrowsingCheck, uint64_t listenerID) 111 DecidePolicyForNavigationActionSync(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, struct WebKit::FrameInfoData originatingFrameInfoData, uint64_t originatingPageID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, WebCore::ResourceResponse redirectResponse, WebKit::UserData userData, enum WebCore::ShouldSkipSafeBrowsingCheck shouldSkipSafeBrowsingCheck) -> (enum WebCore::PolicyAction policyAction, uint64_t newNavigationID, WebKit::DownloadID downloadID, std::optional<WebKit::WebsitePoliciesData> websitePolicies) Delayed111 DecidePolicyForNavigationActionSync(uint64_t frameID, bool isMainFrame, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, struct WebKit::FrameInfoData originatingFrameInfoData, uint64_t originatingPageID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, WebCore::ResourceResponse redirectResponse, WebKit::UserData userData, enum WebCore::ShouldSkipSafeBrowsingCheck shouldSkipSafeBrowsingCheck) -> (enum WebCore::PolicyAction policyAction, uint64_t newNavigationID, WebKit::DownloadID downloadID, std::optional<WebKit::WebsitePoliciesData> websitePolicies) Delayed 112 112 DecidePolicyForNewWindowAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, struct WebKit::NavigationActionData navigationActionData, WebCore::ResourceRequest request, String frameName, uint64_t listenerID, WebKit::UserData userData) 113 113 UnableToImplementPolicy(uint64_t frameID, WebCore::ResourceError error, WebKit::UserData userData) -
trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
r236485 r236512 895 895 std::optional<WebsitePoliciesData> websitePolicies; 896 896 897 if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationActionSync(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), documentLoader->navigationID(), navigationActionData, originatingFrameInfoData, originatingPageID, navigationAction.resourceRequest(), request, redirectResponse, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()), shouldSkipSafeBrowsingCheck), Messages::WebPageProxy::DecidePolicyForNavigationActionSync::Reply(policyAction, newNavigationID, downloadID, websitePolicies))) {897 if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationActionSync(m_frame->frameID(), m_frame->isMainFrame(), SecurityOriginData::fromFrame(coreFrame), documentLoader->navigationID(), navigationActionData, originatingFrameInfoData, originatingPageID, navigationAction.resourceRequest(), request, redirectResponse, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()), shouldSkipSafeBrowsingCheck), Messages::WebPageProxy::DecidePolicyForNavigationActionSync::Reply(policyAction, newNavigationID, downloadID, websitePolicies))) { 898 898 m_frame->didReceivePolicyDecision(listenerID, PolicyAction::Ignore, 0, { }, { }); 899 899 return; -
trunk/Source/WebKit/WebProcess/WebPage/WebFrame.cpp
r236492 r236512 112 112 { 113 113 auto frame = create(std::unique_ptr<WebFrameLoaderClient>(static_cast<WebFrameLoaderClient*>(&coreFrame->loader().client()))); 114 page->send(Messages::WebPageProxy::DidCreateMainFrame(frame->frameID()), page->pageID() , IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);114 page->send(Messages::WebPageProxy::DidCreateMainFrame(frame->frameID()), page->pageID()); 115 115 116 116 frame->m_coreFrame = coreFrame; … … 123 123 { 124 124 auto frame = create(std::make_unique<WebFrameLoaderClient>()); 125 page->send(Messages::WebPageProxy::DidCreateSubframe(frame->frameID()), page->pageID() , IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);125 page->send(Messages::WebPageProxy::DidCreateSubframe(frame->frameID()), page->pageID()); 126 126 127 127 auto coreFrame = Frame::create(page->corePage(), ownerElement, frame->m_frameLoaderClient.get()); -
trunk/Source/WebKit/WebProcess/WebProcess.cpp
r236492 r236512 252 252 253 253 m_webConnection = WebConnectionToUIProcess::create(this); 254 255 // In order to ensure that the asynchronous messages that are used for notifying the UI process256 // about when WebFrame objects come and go are always delivered before the synchronous policy messages,257 // use this flag to force synchronous messages to be treated as asynchronous messages in the UI process258 // unless when doing so would lead to a deadlock.259 connection->setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(true);260 254 } 261 255
Note:
See TracChangeset
for help on using the changeset viewer.