[webkit-changes] [WebKit/WebKit] e90f89: Begin using C++ coroutines for WebPageProxy::decid...

Alex Christensen noreply at github.com
Mon May 20 08:17:16 PDT 2024


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: e90f899882e41a77d0baaa336e347b4e19da3f2f
      https://github.com/WebKit/WebKit/commit/e90f899882e41a77d0baaa336e347b4e19da3f2f
  Author: Alex Christensen <achristensen at apple.com>
  Date:   2024-05-20 (Mon, 20 May 2024)

  Changed paths:
    A Source/WebKit/Platform/CoroutineUtilities.h
    M Source/WebKit/Platform/IPC/Connection.h
    M Source/WebKit/UIProcess/WebPageProxy.cpp
    M Source/WebKit/UIProcess/WebPageProxy.h
    M Source/WebKit/WebKit.xcodeproj/project.pbxproj
    M Tools/TestWebKitAPI/cocoa/HTTPServer.h

  Log Message:
  -----------
  Begin using C++ coroutines for WebPageProxy::decidePolicyForNavigationAction
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



To unsubscribe from these emails, change your notification settings at https://github.com/WebKit/WebKit/settings/notifications


More information about the webkit-changes mailing list