Skip to content
Permalink
Browse files
[iOS] Have ProcessAssertion take the RunningBoard assertion asynchron…
…ously by default

https://bugs.webkit.org/show_bug.cgi?id=225324
<rdar://76972252>

Reviewed by Geoffrey Garen.

Have ProcessAssertion take the RunningBoard assertion asynchronously (on a background thread) by
default as we have evidence that doing so on the main thread is bad for performance and may
negatively impact launch time.

When constructing a ProcessAssertion, the caller can now indicate if it wants the assertion to be
taken asynchronously (default) or not. Bug 227552 is an example of a case where we still want to
take the assertion synchronously (because we're not on the main thread and we need to make sure
we have the assertion before proceeding).

The caller can also provide a completion handler that will get called once the RunningBoard is
taken. Note that the RunningBoard async API ([RBSAssertion acquireWithInvalidationHandler]) does
not provide a way for us to know when the assertion is taken. For this reason, ProcessAssertion
keeps using the RunningBoard sync API ([RBSAssertion acquireWithError:]) but calls in on a
background queue.

For the UIProcess's background task though, we don't need to know when the assertion is taken
so we can use the RunningBoard async API.

Note that the previous iteration of this patch had a bug where the ProcessThrottler would release
its previous assertion before the new one is taken (asynchronously) when changing the assertion
type (e.g. foreground to background). This is addressed in this patch. ProcessThrottler now passes
an acquisition handler when constructing the ProcessAssertion and only releases its previous
assertion once the acquisition handler for the new one is taken.

* NetworkProcess/Downloads/DownloadMap.cpp:
(WebKit::DownloadMap::add):
* NetworkProcess/Downloads/DownloadMap.h:
* Platform/IPC/cocoa/ConnectionCocoa.mm:
(IPC::ConnectionTerminationWatchdog::ConnectionTerminationWatchdog):
* UIProcess/Downloads/DownloadProxyMap.cpp:
(WebKit::DownloadProxyMap::createDownloadProxy):
* UIProcess/Downloads/DownloadProxyMap.h:
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::setWebProcessHasUploads):
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/ProcessAssertion.cpp:
(WebKit::ProcessAssertion::ProcessAssertion):
* UIProcess/ProcessAssertion.h:
(WebKit::ProcessAssertion::create):
* UIProcess/ProcessThrottler.cpp:
(WebKit::ProcessThrottler::setAssertionType):
* UIProcess/ProcessThrottler.h:
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::updateAudibleMediaAssertions):
* UIProcess/WebProcessPool.h:
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::updateAudibleMediaAssertions):
* UIProcess/WebProcessProxy.h:
* UIProcess/ios/ProcessAssertionIOS.mm:
(assertionsWorkQueue):
(-[WKProcessAssertionBackgroundTaskManager _updateBackgroundTask]):
(-[WKProcessAssertionBackgroundTaskManager assertion:didInvalidateWithError:]):
(WebKit::ProcessAssertion::ProcessAssertion):
(WebKit::ProcessAssertion::acquireAsync):
(WebKit::ProcessAssertion::acquireSync):
(WebKit::ProcessAssertion::~ProcessAssertion):
(WebKit::ProcessAssertion::processAssertionWasInvalidated):
(WebKit::ProcessAssertion::isValid const):


Canonical link: https://commits.webkit.org/239425@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279601 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
cdumez committed Jul 6, 2021
1 parent 0e80d01 commit 72e10b892233c2d19bbb448c3eea2449ef7d8e95
Showing 20 changed files with 181 additions and 47 deletions.
@@ -1,3 +1,70 @@
2021-07-06 Chris Dumez <cdumez@apple.com>

[iOS] Have ProcessAssertion take the RunningBoard assertion asynchronously by default
https://bugs.webkit.org/show_bug.cgi?id=225324
<rdar://76972252>

Reviewed by Geoffrey Garen.

Have ProcessAssertion take the RunningBoard assertion asynchronously (on a background thread) by
default as we have evidence that doing so on the main thread is bad for performance and may
negatively impact launch time.

When constructing a ProcessAssertion, the caller can now indicate if it wants the assertion to be
taken asynchronously (default) or not. Bug 227552 is an example of a case where we still want to
take the assertion synchronously (because we're not on the main thread and we need to make sure
we have the assertion before proceeding).

The caller can also provide a completion handler that will get called once the RunningBoard is
taken. Note that the RunningBoard async API ([RBSAssertion acquireWithInvalidationHandler]) does
not provide a way for us to know when the assertion is taken. For this reason, ProcessAssertion
keeps using the RunningBoard sync API ([RBSAssertion acquireWithError:]) but calls in on a
background queue.

For the UIProcess's background task though, we don't need to know when the assertion is taken
so we can use the RunningBoard async API.

Note that the previous iteration of this patch had a bug where the ProcessThrottler would release
its previous assertion before the new one is taken (asynchronously) when changing the assertion
type (e.g. foreground to background). This is addressed in this patch. ProcessThrottler now passes
an acquisition handler when constructing the ProcessAssertion and only releases its previous
assertion once the acquisition handler for the new one is taken.

* NetworkProcess/Downloads/DownloadMap.cpp:
(WebKit::DownloadMap::add):
* NetworkProcess/Downloads/DownloadMap.h:
* Platform/IPC/cocoa/ConnectionCocoa.mm:
(IPC::ConnectionTerminationWatchdog::ConnectionTerminationWatchdog):
* UIProcess/Downloads/DownloadProxyMap.cpp:
(WebKit::DownloadProxyMap::createDownloadProxy):
* UIProcess/Downloads/DownloadProxyMap.h:
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::setWebProcessHasUploads):
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/ProcessAssertion.cpp:
(WebKit::ProcessAssertion::ProcessAssertion):
* UIProcess/ProcessAssertion.h:
(WebKit::ProcessAssertion::create):
* UIProcess/ProcessThrottler.cpp:
(WebKit::ProcessThrottler::setAssertionType):
* UIProcess/ProcessThrottler.h:
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::updateAudibleMediaAssertions):
* UIProcess/WebProcessPool.h:
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::updateAudibleMediaAssertions):
* UIProcess/WebProcessProxy.h:
* UIProcess/ios/ProcessAssertionIOS.mm:
(assertionsWorkQueue):
(-[WKProcessAssertionBackgroundTaskManager _updateBackgroundTask]):
(-[WKProcessAssertionBackgroundTaskManager assertion:didInvalidateWithError:]):
(WebKit::ProcessAssertion::ProcessAssertion):
(WebKit::ProcessAssertion::acquireAsync):
(WebKit::ProcessAssertion::acquireSync):
(WebKit::ProcessAssertion::~ProcessAssertion):
(WebKit::ProcessAssertion::processAssertionWasInvalidated):
(WebKit::ProcessAssertion::isValid const):

2021-07-06 Sihui Liu <sihui_liu@apple.com>

Don't interrupt database for WebResourceLoadStatisticsStore if it will not be suspended
@@ -61,7 +61,7 @@ DownloadMap::DownloadMapType::AddResult DownloadMap::add(DownloadID downloadID,
auto result = m_downloads.add(downloadID, WTFMove(download));
if (m_downloads.size() == 1) {
ASSERT(!m_downloadAssertion);
m_downloadAssertion = makeUnique<ProcessAssertion>(getpid(), "WebKit downloads"_s, ProcessAssertionType::UnboundedNetworking);
m_downloadAssertion = ProcessAssertion::create(getpid(), "WebKit downloads"_s, ProcessAssertionType::UnboundedNetworking);
RELEASE_LOG(ProcessSuspension, "Took 'WebKit downloads' assertion in NetworkProcess");
}

@@ -53,7 +53,7 @@ class DownloadMap {

private:
DownloadMapType m_downloads;
std::unique_ptr<ProcessAssertion> m_downloadAssertion;
RefPtr<ProcessAssertion> m_downloadAssertion;
};

#endif // !ENABLE(TAKE_UNBOUNDED_NETWORKING_ASSERTION)
@@ -577,7 +577,7 @@ class NetworkProcess : public AuxiliaryProcess, private DownloadManager::Client,

#if PLATFORM(IOS_FAMILY)
WebSQLiteDatabaseTracker m_webSQLiteDatabaseTracker;
std::unique_ptr<ProcessAssertion> m_holdingLockedFileAssertion;
RefPtr<ProcessAssertion> m_holdingLockedFileAssertion;
#endif

HashMap<PAL::SessionID, String> m_idbDatabasePaths;
@@ -112,7 +112,7 @@

// We synchronously take a process assertion when beginning a SQLite transaction so that we don't get suspended
// while holding a locked file. We would get killed if suspended while holding locked files.
m_holdingLockedFileAssertion = makeUnique<ProcessAssertion>(getCurrentProcessID(), "Network Process is holding locked files"_s, ProcessAssertionType::FinishTaskUninterruptable);
m_holdingLockedFileAssertion = ProcessAssertion::create(getCurrentProcessID(), "Network Process is holding locked files"_s, ProcessAssertionType::FinishTaskUninterruptable, ProcessAssertion::Mode::Sync);
}

} // namespace WebKit
@@ -89,7 +89,7 @@ static void createConnectionTerminationWatchdog(OSObjectPtr<xpc_connection_t>& x
: m_xpcConnection(xpcConnection)
, m_watchdogTimer(RunLoop::main(), this, &ConnectionTerminationWatchdog::watchdogTimerFired)
#if PLATFORM(IOS_FAMILY)
, m_assertion(makeUnique<WebKit::ProcessAndUIAssertion>(xpc_connection_get_pid(m_xpcConnection.get()), "ConnectionTerminationWatchdog"_s, WebKit::ProcessAssertionType::Background))
, m_assertion(WebKit::ProcessAndUIAssertion::create(xpc_connection_get_pid(m_xpcConnection.get()), "ConnectionTerminationWatchdog"_s, WebKit::ProcessAssertionType::Background))
#endif
{
m_watchdogTimer.startOneShot(interval);
@@ -104,7 +104,7 @@ void watchdogTimerFired()
OSObjectPtr<xpc_connection_t> m_xpcConnection;
RunLoop::Timer<ConnectionTerminationWatchdog> m_watchdogTimer;
#if PLATFORM(IOS_FAMILY)
std::unique_ptr<WebKit::ProcessAndUIAssertion> m_assertion;
Ref<WebKit::ProcessAndUIAssertion> m_assertion;
#endif
};

@@ -55,11 +55,14 @@ NS_ASSUME_NONNULL_BEGIN
+ (RBSTarget *)currentProcess;
@end

@class RBSAssertion;
@protocol RBSAssertionObserving;
typedef void (^RBSAssertionInvalidationHandler)(RBSAssertion *assertion, NSError *error);

@interface RBSAssertion : NSObject
- (instancetype)initWithExplanation:(NSString *)explanation target:(RBSTarget *)target attributes:(NSArray <RBSAttribute *> *)attributes;
- (BOOL)acquireWithError:(NSError **)error;
- (void)acquireWithInvalidationHandler:(nullable RBSAssertionInvalidationHandler)handler;
- (void)invalidate;
- (void)addObserver:(id <RBSAssertionObserving>)observer;
- (void)removeObserver:(id <RBSAssertionObserving>)observer;
@@ -90,10 +90,10 @@ DownloadProxy& DownloadProxyMap::createDownloadProxy(WebsiteDataStore& dataStore

if (m_downloads.size() == 1 && m_shouldTakeAssertion) {
ASSERT(!m_downloadUIAssertion);
m_downloadUIAssertion = makeUnique<ProcessAssertion>(getCurrentProcessID(), "WebKit downloads"_s, ProcessAssertionType::UnboundedNetworking);
m_downloadUIAssertion = ProcessAssertion::create(getCurrentProcessID(), "WebKit downloads"_s, ProcessAssertionType::UnboundedNetworking);

ASSERT(!m_downloadNetworkingAssertion);
m_downloadNetworkingAssertion = makeUnique<ProcessAssertion>(m_process.processIdentifier(), "WebKit downloads"_s, ProcessAssertionType::UnboundedNetworking);
m_downloadNetworkingAssertion = ProcessAssertion::create(m_process.processIdentifier(), "WebKit downloads"_s, ProcessAssertionType::UnboundedNetworking);

RELEASE_LOG(ProcessSuspension, "UIProcess took 'WebKit downloads' assertions for UIProcess and NetworkProcess");
}
@@ -75,8 +75,8 @@ class DownloadProxyMap : public CanMakeWeakPtr<DownloadProxyMap> {
HashMap<DownloadID, RefPtr<DownloadProxy>> m_downloads;

bool m_shouldTakeAssertion { false };
std::unique_ptr<ProcessAssertion> m_downloadUIAssertion;
std::unique_ptr<ProcessAssertion> m_downloadNetworkingAssertion;
RefPtr<ProcessAssertion> m_downloadUIAssertion;
RefPtr<ProcessAssertion> m_downloadNetworkingAssertion;

#if PLATFORM(IOS_FAMILY)
RetainPtr<id> m_backgroundObserver;
@@ -1442,15 +1442,15 @@ void NetworkProcessProxy::setWebProcessHasUploads(WebCore::ProcessIdentifier pro
if (!m_uploadActivity) {
RELEASE_LOG(ProcessSuspension, "NetworkProcessProxy::setWebProcessHasUploads: The number of uploads in progress is now greater than 0. Taking Networking and UI process assertions.");
m_uploadActivity = UploadActivity {
makeUnique<ProcessAssertion>(getCurrentProcessID(), "WebKit uploads"_s, ProcessAssertionType::UnboundedNetworking),
makeUnique<ProcessAssertion>(processIdentifier(), "WebKit uploads"_s, ProcessAssertionType::UnboundedNetworking),
HashMap<WebCore::ProcessIdentifier, std::unique_ptr<ProcessAssertion>>()
ProcessAssertion::create(getCurrentProcessID(), "WebKit uploads"_s, ProcessAssertionType::UnboundedNetworking),
ProcessAssertion::create(processIdentifier(), "WebKit uploads"_s, ProcessAssertionType::UnboundedNetworking),
HashMap<WebCore::ProcessIdentifier, RefPtr<ProcessAssertion>>()
};
}

m_uploadActivity->webProcessAssertions.ensure(processID, [&] {
RELEASE_LOG(ProcessSuspension, "NetworkProcessProxy::setWebProcessHasUploads: Taking upload assertion on behalf of WebProcess with PID %d", process->processIdentifier());
return makeUnique<ProcessAssertion>(process->processIdentifier(), "WebKit uploads"_s, ProcessAssertionType::UnboundedNetworking);
return ProcessAssertion::create(process->processIdentifier(), "WebKit uploads"_s, ProcessAssertionType::UnboundedNetworking);
});
}

@@ -344,9 +344,9 @@ class NetworkProcessProxy final : public AuxiliaryProcessProxy, private ProcessT
#endif

struct UploadActivity {
std::unique_ptr<ProcessAssertion> uiAssertion;
std::unique_ptr<ProcessAssertion> networkAssertion;
HashMap<WebCore::ProcessIdentifier, std::unique_ptr<ProcessAssertion>> webProcessAssertions;
RefPtr<ProcessAssertion> uiAssertion;
RefPtr<ProcessAssertion> networkAssertion;
HashMap<WebCore::ProcessIdentifier, RefPtr<ProcessAssertion>> webProcessAssertions;
};
std::optional<UploadActivity> m_uploadActivity;

@@ -46,6 +46,16 @@ bool ProcessAssertion::isValid() const
return true;
}

void ProcessAssertion::acquireAsync(CompletionHandler<void()>&& completionHandler)
{
if (completionHandler)
RunLoop::main().dispatch(WTFMove(completionHandler));
}

void ProcessAssertion::acquireSync()
{
}

ProcessAndUIAssertion::ProcessAndUIAssertion(ProcessID pid, const String& reason, ProcessAssertionType assertionType)
: ProcessAssertion(pid, reason, assertionType)
{
@@ -25,8 +25,10 @@

#pragma once

#include <wtf/CompletionHandler.h>
#include <wtf/Function.h>
#include <wtf/ProcessID.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/WeakPtr.h>
#include <wtf/text/WTFString.h>

@@ -52,10 +54,22 @@ enum class ProcessAssertionType {
FinishTaskUninterruptable,
};

class ProcessAssertion : public CanMakeWeakPtr<ProcessAssertion> {
class ProcessAssertion : public ThreadSafeRefCounted<ProcessAssertion>, public CanMakeWeakPtr<ProcessAssertion> {
WTF_MAKE_FAST_ALLOCATED;
public:
ProcessAssertion(ProcessID, const String& reason, ProcessAssertionType);
enum class Mode : bool { Sync, Async };
static Ref<ProcessAssertion> create(ProcessID pid, const String& reason, ProcessAssertionType type, Mode mode = Mode::Async, CompletionHandler<void()>&& acquisisionHandler = nullptr)
{
auto assertion = adoptRef(*new ProcessAssertion(pid, reason, type));
if (mode == Mode::Async)
assertion->acquireAsync(WTFMove(acquisisionHandler));
else {
assertion->acquireSync();
if (acquisisionHandler)
acquisisionHandler();
}
return assertion;
}
virtual ~ProcessAssertion();

void setInvalidationHandler(Function<void()>&& handler) { m_invalidationHandler = WTFMove(handler); }
@@ -65,8 +79,13 @@ class ProcessAssertion : public CanMakeWeakPtr<ProcessAssertion> {

bool isValid() const;

#if PLATFORM(IOS_FAMILY)
protected:
ProcessAssertion(ProcessID, const String& reason, ProcessAssertionType);

void acquireAsync(CompletionHandler<void()>&&);
void acquireSync();

#if PLATFORM(IOS_FAMILY)
virtual void processAssertionWasInvalidated();
#endif

@@ -77,20 +96,34 @@ class ProcessAssertion : public CanMakeWeakPtr<ProcessAssertion> {
#if PLATFORM(IOS_FAMILY)
RetainPtr<RBSAssertion> m_rbsAssertion;
RetainPtr<WKRBSAssertionDelegate> m_delegate;
bool m_wasInvalidated { false };
#endif
Function<void()> m_invalidationHandler;
};

class ProcessAndUIAssertion final : public ProcessAssertion {
public:
ProcessAndUIAssertion(ProcessID, const String& reason, ProcessAssertionType);
static Ref<ProcessAndUIAssertion> create(ProcessID pid, const String& reason, ProcessAssertionType type, Mode mode = Mode::Async, CompletionHandler<void()>&& acquisisionHandler = nullptr)
{
auto assertion = adoptRef(*new ProcessAndUIAssertion(pid, reason, type));
if (mode == Mode::Async)
assertion->acquireAsync(WTFMove(acquisisionHandler));
else {
assertion->acquireSync();
if (acquisisionHandler)
acquisisionHandler();
}
return assertion;
}
~ProcessAndUIAssertion();

void uiAssertionWillExpireImminently();

void setUIAssertionExpirationHandler(Function<void()>&& handler) { m_uiAssertionExpirationHandler = WTFMove(handler); }

private:
ProcessAndUIAssertion(ProcessID, const String& reason, ProcessAssertionType);

#if PLATFORM(IOS_FAMILY)
void processAssertionWasInvalidated() final;
#endif
@@ -129,20 +129,21 @@ void ProcessThrottler::setAssertionType(ProcessAssertionType newType)

PROCESSTHROTTLER_RELEASE_LOG("setAssertionType: Updating process assertion type to %u (foregroundActivities=%u, backgroundActivities=%u)", newType, m_foregroundActivities.size(), m_backgroundActivities.size());

// Keep the previous assertion around until after the new one has been created so that we always hold
// a process assertion for the process.
// Keep the previous assertion active until the new assertion is taken asynchronously.
auto previousAssertion = std::exchange(m_assertion, nullptr);
if (m_shouldTakeUIBackgroundAssertion) {
auto assertion = makeUnique<ProcessAndUIAssertion>(m_processIdentifier, assertionName(newType), newType);
assertion->setUIAssertionExpirationHandler([this] {
uiAssertionWillExpireImminently();
auto assertion = ProcessAndUIAssertion::create(m_processIdentifier, assertionName(newType), newType, ProcessAssertion::Mode::Async, [previousAssertion = WTFMove(previousAssertion)] { });
assertion->setUIAssertionExpirationHandler([weakThis = makeWeakPtr(*this)] {
if (weakThis)
weakThis->uiAssertionWillExpireImminently();
});
m_assertion = WTFMove(assertion);
} else
m_assertion = makeUnique<ProcessAssertion>(m_processIdentifier, assertionName(newType), newType);
m_assertion = ProcessAssertion::create(m_processIdentifier, assertionName(newType), newType, ProcessAssertion::Mode::Async, [previousAssertion = WTFMove(previousAssertion)] { });

m_assertion->setInvalidationHandler([this] {
assertionWasInvalidated();
m_assertion->setInvalidationHandler([weakThis = makeWeakPtr(*this)] {
if (weakThis)
weakThis->assertionWasInvalidated();
});
m_process.didSetAssertionType(newType);
}
@@ -149,7 +149,7 @@ class ProcessThrottler : public CanMakeWeakPtr<ProcessThrottler> {

ProcessThrottlerClient& m_process;
ProcessID m_processIdentifier { 0 };
std::unique_ptr<ProcessAssertion> m_assertion;
RefPtr<ProcessAssertion> m_assertion;
RunLoop::Timer<ProcessThrottler> m_prepareToSuspendTimeoutTimer;
HashSet<ForegroundActivity*> m_foregroundActivities;
HashSet<BackgroundActivity*> m_backgroundActivities;
@@ -2032,9 +2032,9 @@ void WebProcessPool::updateAudibleMediaAssertions()

WEBPROCESSPOOL_RELEASE_LOG(ProcessSuspension, "updateAudibleMediaAssertions: The number of processes playing audible media is now greater than zero. Taking UI process assertion.");
m_audibleMediaActivity = AudibleMediaActivity {
makeUniqueRef<ProcessAssertion>(getCurrentProcessID(), "WebKit Media Playback"_s, ProcessAssertionType::MediaPlayback)
ProcessAssertion::create(getCurrentProcessID(), "WebKit Media Playback"_s, ProcessAssertionType::MediaPlayback)
#if ENABLE(GPU_PROCESS)
, gpuProcess() ? makeUnique<ProcessAssertion>(gpuProcess()->processIdentifier(), "WebKit Media Playback"_s, ProcessAssertionType::MediaPlayback) : nullptr
, gpuProcess() ? RefPtr<ProcessAssertion> { ProcessAssertion::create(gpuProcess()->processIdentifier(), "WebKit Media Playback"_s, ProcessAssertionType::MediaPlayback) } : nullptr
#endif
};
}
@@ -771,9 +771,9 @@ class WebProcessPool final
WebProcessWithAudibleMediaCounter m_webProcessWithAudibleMediaCounter;

struct AudibleMediaActivity {
UniqueRef<ProcessAssertion> uiProcessMediaPlaybackAssertion;
Ref<ProcessAssertion> uiProcessMediaPlaybackAssertion;
#if ENABLE(GPU_PROCESS)
std::unique_ptr<ProcessAssertion> gpuProcessMediaPlaybackAssertion;
RefPtr<ProcessAssertion> gpuProcessMediaPlaybackAssertion;
#endif
};
std::optional<AudibleMediaActivity> m_audibleMediaActivity;
@@ -1488,7 +1488,7 @@ void WebProcessProxy::updateAudibleMediaAssertions()
if (newHasAudibleWebPage) {
WEBPROCESSPROXY_RELEASE_LOG(ProcessSuspension, "updateAudibleMediaAssertions: Taking MediaPlayback assertion for WebProcess");
m_audibleMediaActivity = AudibleMediaActivity {
makeUniqueRef<ProcessAssertion>(processIdentifier(), "WebKit Media Playback"_s, ProcessAssertionType::MediaPlayback),
ProcessAssertion::create(processIdentifier(), "WebKit Media Playback"_s, ProcessAssertionType::MediaPlayback),
processPool().webProcessWithAudibleMediaToken()
};
} else {
@@ -636,7 +636,7 @@ class WebProcessProxy : public AuxiliaryProcessProxy, private ProcessThrottlerCl
HashMap<WebCore::SleepDisablerIdentifier, std::unique_ptr<WebCore::SleepDisabler>> m_sleepDisablers;

struct AudibleMediaActivity {
UniqueRef<ProcessAssertion> assertion;
Ref<ProcessAssertion> assertion;
WebProcessWithAudibleMediaToken token;
};
std::optional<AudibleMediaActivity> m_audibleMediaActivity;

0 comments on commit 72e10b8

Please sign in to comment.