Skip to content
Permalink
Browse files
Web Locks held in a Worker are not released on page refresh or exit
https://bugs.webkit.org/show_bug.cgi?id=239614
<rdar://problem/92173575>

Reviewed by Alex Christensen.

Before a web worker olding a lock would terminate, WebLockManager::stop() would get called
and it would attempt to release all locks held by the worker. However, because we're off
the main thread and because the lock registry was held by the Page on the main thread,
we would rely on a call to `workerLoaderProxy().postTaskToLoader()` to get back to the
main thread and access the lock registry via the Document's page. However, this wasn't
reliable because the task posted to postTaskToLoader() could get dropped if the worker's
Document is also going away (which is the case when reloading or navigating away).

To address the issue, the WebLockRegistry can now be accessed directly (on the main thread),
without having to go through a Page. As a result, we can simply do a callOnMainThread()
and then access WebLockRegistry::shared(), which is always reliable. To maintain the
previous behavior for WebKitLegacy, I also partitioned the WebLockRegistry per sessionID
since we don't want views sharing the same locks if one is using the default session and
the other is using a private session. This wasn't an issue for modern WebKit since there
is a single session per WebProcess.

To achieve this, I had to made sure that WorkerOrWorkletGlobalScope::sessionID() was returning
a valid value. This worked for ServiceWorkerGlobalScope but not for other types or workers /
worklets global scopes.

Test: workers/worker-web-lock-released-on-reload.html

* Source/WebKit/UIProcess/WebLockRegistryProxy.cpp:
(WebKit::WebLockRegistryProxy::requestLock):
(WebKit::WebLockRegistryProxy::releaseLock):
(WebKit::WebLockRegistryProxy::abortLockRequest):
(WebKit::WebLockRegistryProxy::snapshot):
(WebKit::WebLockRegistryProxy::clientIsGoingAway):
* Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp:
(WebKit::WebSWContextManagerConnection::installServiceWorker):
* Source/WebKit/WebProcess/Storage/WebSharedWorkerContextManagerConnection.cpp:
(WebKit::WebSharedWorkerContextManagerConnection::launchSharedWorker):
* Source/WebKit/WebProcess/WebCoreSupport/RemoteWebLockRegistry.cpp:
(WebKit::RemoteWebLockRegistry::requestLock):
(WebKit::RemoteWebLockRegistry::releaseLock):
(WebKit::RemoteWebLockRegistry::abortLockRequest):
(WebKit::RemoteWebLockRegistry::snapshot):
(WebKit::RemoteWebLockRegistry::clientIsGoingAway):
* Source/WebKit/WebProcess/WebCoreSupport/RemoteWebLockRegistry.h:
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::m_appHighlightsVisible):
* Source/WebKit/WebProcess/WebProcess.cpp:
(WebKit::WebProcess::WebProcess):
* Source/WebKit/WebProcess/WebProcess.h:
(WebKit::WebProcess::broadcastChannelRegistry):
(WebKit::WebProcess::webLockRegistry): Deleted.
* Source/WebKitLegacy/mac/WebView/WebView.mm:
(-[WebView _commonInitializationWithFrameName:groupName:]):
(-[WebView initSimpleHTMLDocumentWithStyle:frame:preferences:groupName:]):
(getOrCreateWebLockRegistry): Deleted.
* Source/WebKitLegacy/win/WebView.cpp:
(WebView::initWithFrame):
(getOrCreateWebLockRegistry): Deleted.
Test: workers/worker-web-lock-released-on-reload.html
* Source/WebCore/Modules/web-locks/WebLockManager.cpp:
(WebCore::WebLockManager::MainThreadBridge::create):
(WebCore::WebLockManager::MainThreadBridge::MainThreadBridge):
(WebCore::WebLockManager::MainThreadBridge::requestLock):
(WebCore::WebLockManager::MainThreadBridge::releaseLock):
(WebCore::WebLockManager::MainThreadBridge::abortLockRequest):
(WebCore::WebLockManager::MainThreadBridge::query):
(WebCore::WebLockManager::MainThreadBridge::clientIsGoingAway):
(WebCore::WebLockManager::MainThreadBridge::ensureOnMainThread): Deleted.
* Source/WebCore/Modules/web-locks/WebLockRegistry.cpp:
(WebCore::sharedRegistry):
(WebCore::WebLockRegistry::shared):
(WebCore::WebLockRegistry::setSharedRegistry):
(WebCore::LocalWebLockRegistry::ensureRegistryForOrigin):
(WebCore::LocalWebLockRegistry::existingRegistryForOrigin const):
(WebCore::LocalWebLockRegistry::PerOriginRegistry::create):
(WebCore::LocalWebLockRegistry::PerOriginRegistry::PerOriginRegistry):
(WebCore::LocalWebLockRegistry::PerOriginRegistry::~PerOriginRegistry):
(WebCore::LocalWebLockRegistry::requestLock):
(WebCore::LocalWebLockRegistry::releaseLock):
(WebCore::LocalWebLockRegistry::abortLockRequest):
(WebCore::LocalWebLockRegistry::snapshot):
(WebCore::LocalWebLockRegistry::clientIsGoingAway):
(WebCore::LocalWebLockRegistry::clientsAreGoingAway):
* Source/WebCore/Modules/web-locks/WebLockRegistry.h:
* Source/WebCore/Modules/webaudio/AudioWorkletMessagingProxy.cpp:
(WebCore::generateWorkletParameters):
* Source/WebCore/dom/Document.h:
* Source/WebCore/loader/EmptyClients.cpp:
(WebCore::pageConfigurationWithEmptyClients):
* Source/WebCore/page/Page.cpp:
(WebCore::Page::Page):
* Source/WebCore/page/Page.h:
(WebCore::Page::webLockRegistry): Deleted.
* Source/WebCore/page/PageConfiguration.cpp:
(WebCore::PageConfiguration::PageConfiguration):
* Source/WebCore/page/PageConfiguration.h:
* Source/WebCore/workers/Worker.cpp:
(WebCore::Worker::notifyFinished):
* Source/WebCore/workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::WorkerGlobalScope):
* Source/WebCore/workers/WorkerGlobalScopeProxy.h:
* Source/WebCore/workers/WorkerMessagingProxy.cpp:
(WebCore::WorkerMessagingProxy::startWorkerGlobalScope):
* Source/WebCore/workers/WorkerMessagingProxy.h:
* Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp:
(WebCore::WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope):
* Source/WebCore/workers/WorkerOrWorkletGlobalScope.h:
(WebCore::WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope):
* Source/WebCore/workers/WorkerThread.h:
* Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp:
(WebCore::ServiceWorkerGlobalScope::create):
(WebCore::ServiceWorkerGlobalScope::ServiceWorkerGlobalScope):
* Source/WebCore/workers/service/ServiceWorkerGlobalScope.h:
* Source/WebCore/workers/service/context/ServiceWorkerThread.cpp:
(WebCore::ServiceWorkerThread::createWorkerGlobalScope):
* Source/WebCore/workers/shared/context/SharedWorkerThreadProxy.cpp:
(WebCore::generateWorkerParameters):
* Source/WebCore/worklets/WorkletGlobalScope.cpp:
(WebCore::WorkletGlobalScope::WorkletGlobalScope):
* Source/WebCore/worklets/WorkletParameters.h:
(WebCore::WorkletParameters::isolatedCopy const):
(WebCore::WorkletParameters::isolatedCopy):
* LayoutTests/workers/resources/worker-web-lock-released-on-reload-popup.html: Added.
* LayoutTests/workers/resources/worker-web-lock-released-on-reload-worker.js: Added.
* LayoutTests/workers/worker-web-lock-released-on-reload-expected.txt: Added.
* LayoutTests/workers/worker-web-lock-released-on-reload.html: Added.

Canonical link: https://commits.webkit.org/249952@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@293329 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
cdumez committed Apr 25, 2022
1 parent 3d4238a commit e8fea134c1e379a59211b1366b6dce16a82134a6
Show file tree
Hide file tree
Showing 39 changed files with 202 additions and 180 deletions.
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<body>
<script>
worker = new Worker("worker-web-lock-released-on-reload-worker.js");
worker.onmessage = () => {
opener.lockAcquiredByWorker();
};
</script>
</body>
</html>
@@ -0,0 +1,7 @@
navigator.locks.request('worker-lock-123', function() {
postMessage('lock acquired from worker');

return new Promise(resolve => {
// Don't release the lock.
});
});
@@ -0,0 +1,11 @@
Makes sure that web locks acquired by web workers are released on page reload.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS Lock was acquired by the worker
PASS Lock was acquired by the worker
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<body>
<script src="../resources/js-test.js"></script>
<script>
description("Makes sure that web locks acquired by web workers are released on page reload.");
jsTestIsAsync = true;

var didReloadPopup = false;
function lockAcquiredByWorker()
{
testPassed("Lock was acquired by the worker");
if (didReloadPopup) {
setTimeout(finishJSTest, 0);
} else {
timeoutHandle = setTimeout(() => {
clearTimeout(timeoutHandle);
testFailed("Worker failed to acquire the lock after a reload");
finishJSTest();
}, 20000);
setTimeout(() => {
popup.location.reload();
}, 0);
didReloadPopup = true;
}
}

popup = open("resources/worker-web-lock-released-on-reload-popup.html");
</script>
</body>
</html>
@@ -73,7 +73,11 @@ class WebLockManager::MainThreadBridge : public ThreadSafeRefCounted<MainThreadB
if (!clientOrigin)
return nullptr;

return adoptRef(*new MainThreadBridge(*context, WTFMove(*clientOrigin)));
auto sessionID = context->sessionID();
if (!sessionID)
return nullptr;

return adoptRef(*new MainThreadBridge(*context, *sessionID, WTFMove(*clientOrigin)));
}

void requestLock(WebLockIdentifier, const String& name, const Options&, Function<void(bool)>&&, Function<void()>&& lockStolenHandler);
@@ -83,26 +87,24 @@ class WebLockManager::MainThreadBridge : public ThreadSafeRefCounted<MainThreadB
void clientIsGoingAway();

private:
MainThreadBridge(ScriptExecutionContext&, ClientOrigin&&);

void ensureOnMainThread(Function<void(WebLockRegistry&)>&& task);
MainThreadBridge(ScriptExecutionContext&, PAL::SessionID, ClientOrigin&&);

WeakPtr<ScriptExecutionContext> m_context;
const ScriptExecutionContextIdentifier m_clientID;
const PAL::SessionID m_sessionID;
const ClientOrigin m_clientOrigin; // Main thread only.
};

WebLockManager::MainThreadBridge::MainThreadBridge(ScriptExecutionContext& context, ClientOrigin&& clientOrigin)
: m_context(context)
, m_clientID(context.identifier())
WebLockManager::MainThreadBridge::MainThreadBridge(ScriptExecutionContext& context, PAL::SessionID sessionID, ClientOrigin&& clientOrigin)
: m_clientID(context.identifier())
, m_sessionID(sessionID)
, m_clientOrigin(WTFMove(clientOrigin).isolatedCopy())
{
}

void WebLockManager::MainThreadBridge::requestLock(WebLockIdentifier lockIdentifier, const String& name, const Options& options, Function<void(bool)>&& grantedHandler, Function<void()>&& lockStolenHandler)
{
ensureOnMainThread([this, name = crossThreadCopy(name), mode = options.mode, steal = options.steal, ifAvailable = options.ifAvailable, lockIdentifier, grantedHandler = WTFMove(grantedHandler), lockStolenHandler = WTFMove(lockStolenHandler)](auto& registry) mutable {
registry.requestLock(m_clientOrigin, lockIdentifier, m_clientID, name, mode, steal, ifAvailable, [clientID = m_clientID, grantedHandler = WTFMove(grantedHandler)] (bool success) mutable {
callOnMainThread([this, protectedThis = Ref { *this }, name = crossThreadCopy(name), mode = options.mode, steal = options.steal, ifAvailable = options.ifAvailable, lockIdentifier, grantedHandler = WTFMove(grantedHandler), lockStolenHandler = WTFMove(lockStolenHandler)]() mutable {
WebLockRegistry::shared().requestLock(m_sessionID, m_clientOrigin, lockIdentifier, m_clientID, name, mode, steal, ifAvailable, [clientID = m_clientID, grantedHandler = WTFMove(grantedHandler)] (bool success) mutable {
ScriptExecutionContext::ensureOnContextThread(clientID, [grantedHandler = WTFMove(grantedHandler), success](auto&) mutable {
grantedHandler(success);
});
@@ -116,15 +118,15 @@ void WebLockManager::MainThreadBridge::requestLock(WebLockIdentifier lockIdentif

void WebLockManager::MainThreadBridge::releaseLock(WebLockIdentifier lockIdentifier, const String& name)
{
ensureOnMainThread([this, lockIdentifier, name = crossThreadCopy(name)](auto& registry) {
registry.releaseLock(m_clientOrigin, lockIdentifier, m_clientID, name);
callOnMainThread([this, protectedThis = Ref { *this }, lockIdentifier, name = crossThreadCopy(name)] {
WebLockRegistry::shared().releaseLock(m_sessionID, m_clientOrigin, lockIdentifier, m_clientID, name);
});
}

void WebLockManager::MainThreadBridge::abortLockRequest(WebLockIdentifier lockIdentifier, const String& name, CompletionHandler<void(bool)>&& completionHandler)
{
ensureOnMainThread([this, lockIdentifier, name = crossThreadCopy(name), completionHandler = WTFMove(completionHandler)](auto& registry) mutable {
registry.abortLockRequest(m_clientOrigin, lockIdentifier, m_clientID, name, [clientID = m_clientID, completionHandler = WTFMove(completionHandler)](bool wasAborted) mutable {
callOnMainThread([this, protectedThis = Ref { *this }, lockIdentifier, name = crossThreadCopy(name), completionHandler = WTFMove(completionHandler)]() mutable {
WebLockRegistry::shared().abortLockRequest(m_sessionID, m_clientOrigin, lockIdentifier, m_clientID, name, [clientID = m_clientID, completionHandler = WTFMove(completionHandler)](bool wasAborted) mutable {
ScriptExecutionContext::ensureOnContextThread(clientID, [completionHandler = WTFMove(completionHandler), wasAborted](auto&) mutable {
completionHandler(wasAborted);
});
@@ -134,8 +136,8 @@ void WebLockManager::MainThreadBridge::abortLockRequest(WebLockIdentifier lockId

void WebLockManager::MainThreadBridge::query(CompletionHandler<void(Snapshot&&)>&& completionHandler)
{
ensureOnMainThread([this, completionHandler = WTFMove(completionHandler)](auto& registry) mutable {
registry.snapshot(m_clientOrigin, [clientID = m_clientID, completionHandler = WTFMove(completionHandler)](Snapshot&& snapshot) mutable {
callOnMainThread([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)]() mutable {
WebLockRegistry::shared().snapshot(m_sessionID, m_clientOrigin, [clientID = m_clientID, completionHandler = WTFMove(completionHandler)](Snapshot&& snapshot) mutable {
ScriptExecutionContext::ensureOnContextThread(clientID, [completionHandler = WTFMove(completionHandler), snapshot = crossThreadCopy(snapshot)](auto&) mutable {
completionHandler(WTFMove(snapshot));
});
@@ -145,30 +147,11 @@ void WebLockManager::MainThreadBridge::query(CompletionHandler<void(Snapshot&&)>

void WebLockManager::MainThreadBridge::clientIsGoingAway()
{
ensureOnMainThread([this](auto& registry) {
registry.clientIsGoingAway(m_clientOrigin, m_clientID);
callOnMainThread([this, protectedThis = Ref { *this }] {
WebLockRegistry::shared().clientIsGoingAway(m_sessionID, m_clientOrigin, m_clientID);
});
}

void WebLockManager::MainThreadBridge::ensureOnMainThread(Function<void(WebLockRegistry&)>&& task)
{
if (!m_context)
return;
ASSERT(m_context->isContextThread());

if (is<Document>(*m_context)) {
if (auto page = downcast<Document>(*m_context).page()) {
Ref protectedThis { *this };
task(page->webLockRegistry());
}
} else {
downcast<WorkerGlobalScope>(*m_context).thread().workerLoaderProxy().postTaskToLoader([task = WTFMove(task), protectedThis = Ref { *this }](auto& context) {
if (auto page = downcast<Document>(context).page())
task(page->webLockRegistry());
});
}
}

Ref<WebLockManager> WebLockManager::create(NavigatorBase& navigator)
{
auto manager = adoptRef(*new WebLockManager(navigator));
@@ -35,9 +35,29 @@

namespace WebCore {

static RefPtr<WebLockRegistry>& sharedRegistry()
{
static MainThreadNeverDestroyed<RefPtr<WebLockRegistry>> registry;
return registry;
}

WebLockRegistry& WebLockRegistry::shared()
{
auto& registry = sharedRegistry();
if (!registry)
registry= LocalWebLockRegistry::create();
return *registry;
}

void WebLockRegistry::setSharedRegistry(Ref<WebLockRegistry>&& registry)
{
ASSERT(!sharedRegistry());
sharedRegistry() = WTFMove(registry);
}

class LocalWebLockRegistry::PerOriginRegistry : public RefCounted<PerOriginRegistry>, public CanMakeWeakPtr<PerOriginRegistry> {
public:
static Ref<PerOriginRegistry> create(LocalWebLockRegistry&, const ClientOrigin&);
static Ref<PerOriginRegistry> create(LocalWebLockRegistry&, PAL::SessionID, const ClientOrigin&);
~PerOriginRegistry();

struct LockInfo {
@@ -55,7 +75,7 @@ class LocalWebLockRegistry::PerOriginRegistry : public RefCounted<PerOriginRegis
void clientsAreGoingAway(const Function<bool(const LockInfo&)>& matchClient);

private:
PerOriginRegistry(LocalWebLockRegistry&, const ClientOrigin&);
PerOriginRegistry(LocalWebLockRegistry&, PAL::SessionID, const ClientOrigin&);

struct LockRequest : LockInfo {
String name;
@@ -66,6 +86,7 @@ class LocalWebLockRegistry::PerOriginRegistry : public RefCounted<PerOriginRegis
bool isGrantable(const LockRequest&) const;

WeakPtr<LocalWebLockRegistry> m_globalRegistry;
PAL::SessionID m_sessionID;
ClientOrigin m_clientOrigin;
FastRobinHoodHashMap<String, Deque<LockRequest>> m_lockRequestQueueMap;
FastRobinHoodHashMap<String, Vector<LockInfo>> m_heldLocks;
@@ -75,40 +96,41 @@ LocalWebLockRegistry::LocalWebLockRegistry() = default;

LocalWebLockRegistry::~LocalWebLockRegistry() = default;

auto LocalWebLockRegistry::ensureRegistryForOrigin(const ClientOrigin& clientOrigin) -> Ref<PerOriginRegistry>
auto LocalWebLockRegistry::ensureRegistryForOrigin(PAL::SessionID sessionID, const ClientOrigin& clientOrigin) -> Ref<PerOriginRegistry>
{
if (auto existingRegistry = m_perOriginRegistries.get(clientOrigin))
if (auto existingRegistry = m_perOriginRegistries.get({ sessionID, clientOrigin }))
return *existingRegistry;

return PerOriginRegistry::create(*this, clientOrigin);
return PerOriginRegistry::create(*this, sessionID, clientOrigin);
}

auto LocalWebLockRegistry::existingRegistryForOrigin(const ClientOrigin& clientOrigin) const -> RefPtr<PerOriginRegistry>
auto LocalWebLockRegistry::existingRegistryForOrigin(PAL::SessionID sessionID, const ClientOrigin& clientOrigin) const -> RefPtr<PerOriginRegistry>
{
return m_perOriginRegistries.get(clientOrigin).get();
return m_perOriginRegistries.get({ sessionID, clientOrigin }).get();
}

Ref<LocalWebLockRegistry::PerOriginRegistry> LocalWebLockRegistry::PerOriginRegistry::create(LocalWebLockRegistry& globalRegistry, const ClientOrigin& clientOrigin)
Ref<LocalWebLockRegistry::PerOriginRegistry> LocalWebLockRegistry::PerOriginRegistry::create(LocalWebLockRegistry& globalRegistry, PAL::SessionID sessionID, const ClientOrigin& clientOrigin)
{
return adoptRef(*new PerOriginRegistry(globalRegistry, clientOrigin));
return adoptRef(*new PerOriginRegistry(globalRegistry, sessionID, clientOrigin));
}

LocalWebLockRegistry::PerOriginRegistry::PerOriginRegistry(LocalWebLockRegistry& globalRegistry, const ClientOrigin& clientOrigin)
LocalWebLockRegistry::PerOriginRegistry::PerOriginRegistry(LocalWebLockRegistry& globalRegistry, PAL::SessionID sessionID, const ClientOrigin& clientOrigin)
: m_globalRegistry(globalRegistry)
, m_sessionID(sessionID)
, m_clientOrigin(clientOrigin)
{
globalRegistry.m_perOriginRegistries.add(clientOrigin, WeakPtr { * this });
globalRegistry.m_perOriginRegistries.add({ sessionID, clientOrigin }, WeakPtr { * this });
}

LocalWebLockRegistry::PerOriginRegistry::~PerOriginRegistry()
{
if (m_globalRegistry)
m_globalRegistry->m_perOriginRegistries.remove(m_clientOrigin);
m_globalRegistry->m_perOriginRegistries.remove({ m_sessionID, m_clientOrigin });
}

void LocalWebLockRegistry::requestLock(const ClientOrigin& clientOrigin, WebLockIdentifier lockIdentifier, ScriptExecutionContextIdentifier clientID, const String& name, WebLockMode mode, bool steal, bool ifAvailable, Function<void(bool)>&& grantedHandler, Function<void()>&& lockStolenHandler)
void LocalWebLockRegistry::requestLock(PAL::SessionID sessionID, const ClientOrigin& clientOrigin, WebLockIdentifier lockIdentifier, ScriptExecutionContextIdentifier clientID, const String& name, WebLockMode mode, bool steal, bool ifAvailable, Function<void(bool)>&& grantedHandler, Function<void()>&& lockStolenHandler)
{
ensureRegistryForOrigin(clientOrigin)->requestLock(lockIdentifier, clientID, name, mode, steal, ifAvailable, WTFMove(grantedHandler), WTFMove(lockStolenHandler));
ensureRegistryForOrigin(sessionID, clientOrigin)->requestLock(lockIdentifier, clientID, name, mode, steal, ifAvailable, WTFMove(grantedHandler), WTFMove(lockStolenHandler));
}

// https://wicg.github.io/web-locks/#request-a-lock
@@ -135,9 +157,9 @@ void LocalWebLockRegistry::PerOriginRegistry::requestLock(WebLockIdentifier lock
processLockRequestQueue(name, queue);
}

void LocalWebLockRegistry::releaseLock(const ClientOrigin& clientOrigin, WebLockIdentifier lockIdentifier, ScriptExecutionContextIdentifier, const String& name)
void LocalWebLockRegistry::releaseLock(PAL::SessionID sessionID, const ClientOrigin& clientOrigin, WebLockIdentifier lockIdentifier, ScriptExecutionContextIdentifier, const String& name)
{
if (auto registry = existingRegistryForOrigin(clientOrigin))
if (auto registry = existingRegistryForOrigin(sessionID, clientOrigin))
registry->releaseLock(lockIdentifier, name);
}

@@ -158,9 +180,9 @@ void LocalWebLockRegistry::PerOriginRegistry::releaseLock(WebLockIdentifier lock
processLockRequestQueue(name, queueIterator->value);
}

void LocalWebLockRegistry::abortLockRequest(const ClientOrigin& clientOrigin, WebLockIdentifier lockIdentifier, ScriptExecutionContextIdentifier, const String& name, CompletionHandler<void(bool)>&& completionHandler)
void LocalWebLockRegistry::abortLockRequest(PAL::SessionID sessionID, const ClientOrigin& clientOrigin, WebLockIdentifier lockIdentifier, ScriptExecutionContextIdentifier, const String& name, CompletionHandler<void(bool)>&& completionHandler)
{
auto registry = existingRegistryForOrigin(clientOrigin);
auto registry = existingRegistryForOrigin(sessionID, clientOrigin);
if (!registry)
return completionHandler(false);

@@ -222,9 +244,9 @@ void LocalWebLockRegistry::PerOriginRegistry::processLockRequestQueue(const Stri
ASSERT_UNUSED(removedQueue, removedQueue.isEmpty());
}

void LocalWebLockRegistry::snapshot(const ClientOrigin& clientOrigin, CompletionHandler<void(WebLockManager::Snapshot&&)>&& completionHandler)
void LocalWebLockRegistry::snapshot(PAL::SessionID sessionID, const ClientOrigin& clientOrigin, CompletionHandler<void(WebLockManager::Snapshot&&)>&& completionHandler)
{
auto registry = existingRegistryForOrigin(clientOrigin);
auto registry = existingRegistryForOrigin(sessionID, clientOrigin);
if (!registry)
return completionHandler({ });

@@ -247,9 +269,9 @@ void LocalWebLockRegistry::PerOriginRegistry::snapshot(CompletionHandler<void(We
completionHandler(WTFMove(snapshot));
}

void LocalWebLockRegistry::clientIsGoingAway(const ClientOrigin& clientOrigin, ScriptExecutionContextIdentifier clientID)
void LocalWebLockRegistry::clientIsGoingAway(PAL::SessionID sessionID, const ClientOrigin& clientOrigin, ScriptExecutionContextIdentifier clientID)
{
if (auto registry = existingRegistryForOrigin(clientOrigin))
if (auto registry = existingRegistryForOrigin(sessionID, clientOrigin))
registry->clientsAreGoingAway([clientID](auto& lockInfo) { return lockInfo.clientID == clientID; });
}

@@ -291,9 +313,9 @@ void LocalWebLockRegistry::PerOriginRegistry::clientsAreGoingAway(const Function

void LocalWebLockRegistry::clientsAreGoingAway(ProcessIdentifier processIdentifier)
{
Vector<ClientOrigin> clientOrigins = copyToVector(m_perOriginRegistries.keys());
for (auto& clientOrigin : clientOrigins) {
if (auto registry = existingRegistryForOrigin(clientOrigin))
Vector<std::pair<PAL::SessionID, ClientOrigin>> clientOrigins = copyToVector(m_perOriginRegistries.keys());
for (auto& [sessionID, clientOrigin] : clientOrigins) {
if (auto registry = existingRegistryForOrigin(sessionID, clientOrigin))
registry->clientsAreGoingAway([processIdentifier](auto& lockInfo) { return lockInfo.clientID.processIdentifier() == processIdentifier; });
}
}

0 comments on commit e8fea13

Please sign in to comment.