Skip to content
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

Commits on May 20, 2024

  1. Begin using C++ coroutines for WebPageProxy::decidePolicyForNavigatio…

    …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
    achristensen07 committed May 20, 2024
    Configuration menu
    Copy the full SHA
    e90f899 View commit details
    Browse the repository at this point in the history