-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Begin using C++ coroutines for WebPageProxy::decidePolicyForNavigationAction #23021
Conversation
EWS run on previous version of this PR (hash 56710cd) |
56710cd
to
2e44d1a
Compare
EWS run on previous version of this PR (hash 2e44d1a) |
2e44d1a
to
abec41a
Compare
EWS run on previous version of this PR (hash abec41a) |
abec41a
to
09ea55c
Compare
EWS run on previous version of this PR (hash 09ea55c) |
09ea55c
to
ed3d5ee
Compare
EWS run on previous version of this PR (hash ed3d5ee) |
ed3d5ee
to
4798912
Compare
EWS run on previous version of this PR (hash 4798912) |
4798912
to
1a8f831
Compare
EWS run on previous version of this PR (hash 1a8f831) |
1a8f831
to
3c93b0e
Compare
EWS run on previous version of this PR (hash 3c93b0e) |
@@ -7074,6 +7088,15 @@ void WebPageProxy::decidePolicyForNavigationAction(Ref<WebProcessProxy>&& proces | |||
sendCachedLinkDecorationFilteringData(); | |||
#endif | |||
|
|||
transaction = std::nullopt; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is clearly not ratified in the style guide, but I think we're leaning towards { }
instead of std::nullopt
nowadays.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's definitely debatable. 832 vs 1362 instances of each.
#if __has_include(<coroutine>) | ||
#include <coroutine> | ||
#else | ||
#include <experimental/coroutine> | ||
namespace std { | ||
using std::experimental::coroutine_handle; | ||
using std::experimental::suspend_never; | ||
using std::experimental::suspend_always; | ||
} | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is <coroutine>
not part of all toolchains we build against? Is this for macOS downlevels or for the ports using GCC?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In either case, maybe add a FIXME to simplify this when it's unnecessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is needed for some old macOS still. Something similar is done in HTTPServer.h. We can remove it at some point, you're right.
3c93b0e
to
46de710
Compare
EWS run on current version of this PR (hash 46de710) |
β¦nAction https://bugs.webkit.org/show_bug.cgi?id=267827 Reviewed by Abrar Rahman Protyasha. WebKit has a long history with C++ and asynchrony. Deciding whether to proceed with a navigation has always had the ability to be done asynchronously. Before C++11, we made our own object that contained state and context for a call to indicate continuation. With https://commits.webkit.org/193766@main we finished the transition from this object, WebCore::PolicyCallback, to C++ lambdas. Since then, a large and growing amount of our code has developed the ability to do things asynchronously using WTF::CompletionHandler, a std::function-like object that contains state and context to use when continuing. Also since then, C++ has added coroutine support in C++20, including the co_await keyword. This has the potential to allow us to more elegantly write code that does many things asynchronously. WebPageProxy::decidePolicyForNavigationAction has a growing amount of complexity, with deeply nested lambdas and many functions calling another function to continue the logic, trying to break up the logic. With site isolation, I've needed to add many things to this already complex area of the code, and more are needed still. I've had difficulty passing parameters from one end of the flow to the other, through the many nested lambdas. This has led me to do introduce things like ProvisionalPageProxy's needsCookieAccessAddedInNetworkProcess, where I set a bool early in the flow and query the bool much later in the flow. This needs a better solution. In order to begin using C++ coroutines, we need a way to get into a coroutine from a function with a CompletionHandler parameter, and we also need a way to get from a coroutine to a function with a CompletionHandler parameter and await its result. For these two operations, I introduce CoroutineCaller and AwaitableTaskWithCompletionHandler. Task is the object that an asynchronous coroutine returns. Lazy<T> is what a coroutine returns for its resulting T to be awaitable, analogous to a CompletionHandler<void(T)> which is called with the resulting T. These primitives are used to make WebPageProxy::decidePolicyForNavigationAction an asynchronous coroutine. The introduction of this new technology in such a small scope makes it look like most of the code is just the CoroutineCaller/AwaitableTaskWithCompletionHandler borders to call to and from existing code, but as coroutine adoption increases we will see simpler and simpler code, where we can easily and elegantly add new steps in the logic flow by just awaiting another asynchronous step or calling a synchronous step directly. * Source/WebKit/Platform/CoroutineUtilities.h: Added. (WebKit::CoroutineHandle::CoroutineHandle): (WebKit::CoroutineHandle::operator=): (WebKit::CoroutineHandle::~CoroutineHandle): (WebKit::CoroutineHandle::handle const): (WebKit::Lazy::PromiseBase::initial_suspend): (WebKit::Lazy::PromiseBase::unhandled_exception): (WebKit::Lazy::PromiseBase::setHandle): (WebKit::Lazy::PromiseBase::handle): (WebKit::Lazy::Promise<void>::get_return_object): (WebKit::Lazy::Promise<void>::return_void): (WebKit::Lazy::Promise<void>::result): (WebKit::Lazy::Awaitable::Awaitable): (WebKit::Lazy::Awaitable::await_ready const): (WebKit::Lazy::Awaitable::await_suspend): (WebKit::Lazy::Awaitable::await_resume): (WebKit::Lazy::Lazy): (WebKit::Lazy::operator co_await const): (WebKit::Task::promise_type::get_return_object): (WebKit::Task::promise_type::initial_suspend): (WebKit::Task::promise_type::unhandled_exception): (WebKit::Task::promise_type::return_void): (WebKit::CoroutineCaller::setCoroutine): (WebKit::callCoroutine): (WebKit::AwaitableTaskWithCompletionHandler::AwaitableTaskWithCompletionHandler): (WebKit::AwaitableTaskWithCompletionHandler::await_ready): (WebKit::AwaitableTaskWithCompletionHandler::await_suspend): (WebKit::AwaitableTaskWithCompletionHandler::await_resume): * Source/WebKit/Platform/IPC/Connection.h: * Source/WebKit/UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::decidePolicyForNavigationAction): (WebKit::WebPageProxy::awaitableDecidePolicyForNavigationAction): (WebKit::WebPageProxy::continueDecidePolicyForNavigationAction): * Source/WebKit/UIProcess/WebPageProxy.h: * Source/WebKit/WebKit.xcodeproj/project.pbxproj: Canonical link: https://commits.webkit.org/278995@main
46de710
to
e90f899
Compare
Committed 278995@main (e90f899): https://commits.webkit.org/278995@main Reviewed commits have been landed. Closing PR #23021 and removing active labels. |
e90f899
46de710