Chromium Code Reviews| Index: third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannelConnection.cpp |
| diff --git a/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannelConnection.cpp b/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannelConnection.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..eec2d1eb240e27714f2e44be5ba78ad3f403f36b |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannelConnection.cpp |
| @@ -0,0 +1,104 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "modules/broadcastchannel/BroadcastChannelConnection.h" |
| + |
| +#include "platform/ThreadSafeFunctional.h" |
| +#include "platform/mojo/MojoHelper.h" |
| +#include "public/platform/Platform.h" |
| +#include "public/platform/ServiceRegistry.h" |
| +#include "public/platform/WebTaskRunner.h" |
| +#include "public/platform/WebTraceLocation.h" |
| + |
| +namespace blink { |
| + |
| +namespace { |
| + |
| +void connectToService(webmessaging::mojom::blink::BroadcastChannelServiceRequest request) |
| +{ |
| + DCHECK(Platform::current()->mainThread()->isCurrentThread()); |
| + Platform::current()->serviceRegistry()->connectToRemoteService(std::move(request)); |
| +} |
| + |
| +webmessaging::mojom::blink::BroadcastChannelServicePtr& getThreadSpecificService() |
| +{ |
| + DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<webmessaging::mojom::blink::BroadcastChannelServicePtr>, service, new ThreadSpecific<webmessaging::mojom::blink::BroadcastChannelServicePtr>); |
| + if (!service.isSet()) { |
| + Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_HERE, |
| + threadSafeBind(&connectToService, passed(mojo::GetProxy(&*service)))); |
| + } |
| + return *service; |
| +} |
| + |
| +using ConnectionKey = std::pair<RefPtr<SecurityOrigin>, String>; |
| +using ConnectionMap = HashMap<ConnectionKey, BroadcastChannelConnection*>; |
| + |
| +ConnectionMap* getConnectionMap() |
| +{ |
| + DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<ConnectionMap>, connectionMap, new ThreadSpecific<ConnectionMap>); |
|
haraken
2016/06/02 04:23:41
It's a bit nasty to use thread-local storage for t
Marijn Kruisselbrink
2016/06/02 18:33:29
All BroadcastChannel instances that share thread,
|
| + return connectionMap; |
| +} |
| + |
| +} // namespace |
| + |
| +// static |
| +BroadcastChannelConnection* BroadcastChannelConnection::getForChannel(const RefPtr<SecurityOrigin>& origin, const String& name) |
| +{ |
| + ConnectionMap* connectionMap = getConnectionMap(); |
| + auto it = connectionMap->find(ConnectionKey(origin, name)); |
| + if (it != connectionMap->end()) |
| + return it->value; |
| + |
| + webmessaging::mojom::blink::BroadcastChannelServicePtr& service = getThreadSpecificService(); |
| + webmessaging::mojom::blink::BroadcastChannelClientAssociatedPtrInfo localClientInfo; |
| + BroadcastChannelConnection* connection = new BroadcastChannelConnection(name, origin, &localClientInfo, service.associated_group()); |
| + service->Subscribe(origin, name, std::move(localClientInfo)); |
| + return connection; |
| +} |
| + |
| +BroadcastChannelConnection::~BroadcastChannelConnection() |
| +{ |
| + getConnectionMap()->remove(ConnectionKey(m_origin, m_name)); |
| + for (Client* client : m_clients) |
| + client->onError(); |
| +} |
| + |
| +void BroadcastChannelConnection::registerClient(Client* client) |
| +{ |
| + m_clients.add(client); |
| +} |
| + |
| +void BroadcastChannelConnection::unregisterClient(Client* client) |
| +{ |
| + m_clients.remove(client); |
| + if (m_clients.isEmpty()) |
| + delete this; |
|
haraken
2016/06/02 04:23:41
Can we use a unique_ptr to avoid calling manual de
Marijn Kruisselbrink
2016/06/02 18:33:29
The lifetime of this class is mostly managed by th
haraken
2016/06/03 05:33:03
We normally use a dispose() method to promptly dis
|
| +} |
| + |
| +void BroadcastChannelConnection::broadcast(Client* from, const String& message) |
| +{ |
| + for (Client* client : m_clients) { |
| + if (client != from) |
| + client->onMessage(message); |
| + } |
| + getThreadSpecificService()->Broadcast(from->origin(), from->name(), message); |
| +} |
| + |
| +BroadcastChannelConnection::BroadcastChannelConnection(const String& name, const RefPtr<SecurityOrigin>& origin, webmessaging::mojom::blink::BroadcastChannelClientAssociatedPtrInfo* clientInfo, mojo::AssociatedGroup* associatedGroup) |
| + : m_name(name) |
| + , m_origin(origin) |
| + , m_binding(this, clientInfo, associatedGroup) |
| +{ |
| + auto result = getConnectionMap()->set(ConnectionKey(m_origin, m_name), this); |
| + DCHECK(result.isNewEntry) << "There should only be one connection per channel per thread."; |
| + ALLOW_UNUSED_LOCAL(result); |
| +} |
| + |
| +void BroadcastChannelConnection::OnMessage(const String& message) |
| +{ |
| + for (Client* client : m_clients) |
| + client->onMessage(message); |
| +} |
| + |
| +} // namespace blink |