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 |