On Tue, Apr 7, 2020 at 4:58 PM John Abd-El-Malek <j...@google.com> wrote:On Tue, Apr 7, 2020 at 4:43 PM Scott Violet <s...@google.com> wrote:To make it clear to everyone: the issue is that DidFinishNavigation would be fired while DidStartNavigation is below in the stack. And it's probably against the current contract that some observers would then only see DidFinishNavigation without a DidStartNavigation.We could use a NavigationThrottle for that in WebLayer, e.g. in the WCO::DiddStartNavigation if Stop() is called we can record this and then when the NavigationThrottle's start method is called later it can cancel the navigation. However for redirects Scott fond it's a different order: the throttle is called before the corresponding WCO method. So we'd have to either defer all redirects until we see what the embedder says when we call them in the WCO method, or we'd have to call the embedder in the throttle's redirect callback.Here's the patch doing what John outlines: https://chromium-review.googlesource.com/c/chromium/src/+/2141232 . It's mildly tricky, but ensures Stop() is called during notifying observers.-Scott
--
You received this message because you are subscribed to the Google Groups "navigation-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to navigation-de...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/navigation-dev/CALHg4nnDsU14jr0OwJdyPfj-Pab6fBkYKkt%2BVtO%2BmXbmB0i9Nw%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/navigation-dev/CAHtyhaRKAj0Tc1g4k6cpJvZWj2Z9OXX%2BdwEMkD%3D4qe7RChU%3DPA%40mail.gmail.com.
In general, WebContentsObserver is an interface for observing events and observers should not be making changes directly as part of the observation. This is especially true for navigations, since the navigation code is not reentrancy safe. While the proposed patches seem fine in pure code perspective, I don't think that Stop() is the only method that will need to be accounted for and making the navigation system reentrant safe will be non-trivial change.Could we design the API to make these sorts of calling patterns harder to do or discouraged?
+naviga...@chromium.orgIf I had to guess, I would say that WebView might have the same problem as well.For example, we have been chasing some mysterious WebView-specific navigation bugs and one of the theories is that something strange happens in one of the "process has crashed" callbacks.It might be a confirmation bias, but given that we synchronously dispatch callback to WebView, I guess that reentrancy might be a problem worth solving in content/ layer.I like the idea behind this patch, but I think we would be able to make this cleaner by having an explicit scope:void WebContentsImpl::DidStartNavigation() {DispatchingCallbacksScope scope; // runs stored callbacks when destroyed.observers->DidFinishNavigation();}void WebContentsImpl::Stop() {if (DispatchingCallbacksScope::Get()) {DispatchingCallbacksScope::Defer(Bind(&Stop, GetWeakPtr()); // or PostTaskreturn;}// ...}WDYT?
In general, WebContentsObserver is an interface for observing events and observers should not be making changes directly as part of the observation.
This is especially true for navigations, since the navigation code is not reentrancy safe. While the proposed patches seem fine in pure code perspective, I don't think that Stop() is the only method that will need to be accounted for and making the navigation system reentrant safe will be non-trivial change.
Could we design the API to make these sorts of calling patterns harder to do or discouraged?
I'll go with the fix in weblayer then. If no one is opposed to it, I can also add a DCHECK for the Stop() case. We can extend the DCHECK to other places if necessary.-ScottOn Thu, Apr 9, 2020 at 11:02 AM Nasko Oskov <na...@chromium.org> wrote:If we can make the WebLayer API more robust to this, hiding it in its implementation would be great. I'm not opposed to the proposed solution inside content, but I'm afraid of folks looking at the code and that reentrancy works for Stop and then expecting all other APIs to work that way.