diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-04 02:00:56 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-04 02:00:56 +0000 |
commit | a5da6d613f41ecf35c027e8744dd6d3a41e4010c (patch) | |
tree | dad6a3e159fcc21df62180f481a0024db97d5b0d /webkit | |
parent | e23ed5427d0892d07480781f45b4367adebc0c00 (diff) | |
download | chromium_src-a5da6d613f41ecf35c027e8744dd6d3a41e4010c.zip chromium_src-a5da6d613f41ecf35c027e8744dd6d3a41e4010c.tar.gz chromium_src-a5da6d613f41ecf35c027e8744dd6d3a41e4010c.tar.bz2 |
Cross-process Message Port implementation.
I'm sending this first, then I'll add support to workers in another changelist to avoid making this change larger.
TEST=running message port related layout tests in ui_tests
Review URL: http://codereview.chromium.org/159372
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22356 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/api/public/WebKitClient.h | 8 | ||||
-rw-r--r-- | webkit/api/public/WebMessagePortChannel.h | 58 | ||||
-rw-r--r-- | webkit/api/public/WebMessagePortChannelClient.h | 50 | ||||
-rw-r--r-- | webkit/api/src/PlatformMessagePortChannel.cpp | 248 | ||||
-rw-r--r-- | webkit/api/src/PlatformMessagePortChannel.h | 93 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_webkit_init.h | 4 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_worker/test_worker_main.cc | 4 | ||||
-rw-r--r-- | webkit/webkit.gyp | 10 |
8 files changed, 475 insertions, 0 deletions
diff --git a/webkit/api/public/WebKitClient.h b/webkit/api/public/WebKitClient.h index a63ae3d..026caf5 100644 --- a/webkit/api/public/WebKitClient.h +++ b/webkit/api/public/WebKitClient.h @@ -41,6 +41,7 @@ namespace WebKit { class WebClipboard; class WebData; + class WebMessagePortChannel; class WebMimeRegistry; class WebPluginListBuilder; class WebSandboxSupport; @@ -95,6 +96,13 @@ namespace WebKit { virtual bool isLinkVisited(unsigned long long linkHash) = 0; + // Message Ports ------------------------------------------------------- + + // Creates a Message Port Channel. This can be called on any thread. + // The returned object should only be used on the thread it was created on. + virtual WebMessagePortChannel* createMessagePortChannel() = 0; + + // Network ------------------------------------------------------------- virtual void setCookies( diff --git a/webkit/api/public/WebMessagePortChannel.h b/webkit/api/public/WebMessagePortChannel.h new file mode 100644 index 0000000..9ad521c --- /dev/null +++ b/webkit/api/public/WebMessagePortChannel.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebMessagePortChannel_h +#define WebMessagePortChannel_h + +#include "WebCommon.h" + +namespace WebKit { + class WebMessagePortChannelClient; + class WebString; + + // Provides an interface to a Message Port Channel implementation. The object owns itself and + // is signalled that its not needed anymore with the destroy() call. + class WebMessagePortChannel { + public: + virtual void setClient(WebMessagePortChannelClient*) = 0; + virtual void destroy() = 0; + // WebKit versions of WebCore::MessagePortChannel. + virtual void entangle(WebMessagePortChannel*) = 0; + // If sending a message port, callee receives ownership of the object. + virtual void postMessage(const WebString&, WebMessagePortChannel*) = 0; + virtual bool tryGetMessage(WebString*, WebMessagePortChannel**) = 0; + + protected: + virtual ~WebMessagePortChannel() { } + }; + +} // namespace WebKit + +#endif diff --git a/webkit/api/public/WebMessagePortChannelClient.h b/webkit/api/public/WebMessagePortChannelClient.h new file mode 100644 index 0000000..af20d9a --- /dev/null +++ b/webkit/api/public/WebMessagePortChannelClient.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebMessagePortChannelClient_h +#define WebMessagePortChannelClient_h + +namespace WebKit { + + // Provides an interface for users of WebMessagePortChannel to be notified + // when messages are available. + class WebMessagePortChannelClient { + public: + // Alerts that new messages have arrived, which are retrieved by calling + // WebMessagePortChannel::tryGetMessage. Note that this may be called + // on any thread. + virtual void messageAvailable() = 0; + protected: + virtual ~WebMessagePortChannelClient() { } + }; + +} // namespace WebKit + +#endif diff --git a/webkit/api/src/PlatformMessagePortChannel.cpp b/webkit/api/src/PlatformMessagePortChannel.cpp new file mode 100644 index 0000000..72a626a --- /dev/null +++ b/webkit/api/src/PlatformMessagePortChannel.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PlatformMessagePortChannel.h" + +#include "WebKit.h" +#include "WebKitClient.h" +#include "WebMessagePortChannel.h" +#include "WebString.h" + +#include "MessagePort.h" +#include "ScriptExecutionContext.h" + +using namespace WebKit; + +namespace WebCore { + +PassOwnPtr<MessagePortChannel> MessagePortChannel::create(PassRefPtr<PlatformMessagePortChannel> channel) +{ + return new MessagePortChannel(channel); +} + +void MessagePortChannel::createChannel(PassRefPtr<MessagePort> port1, PassRefPtr<MessagePort> port2) +{ + PlatformMessagePortChannel::createChannel(port1, port2); +} + +MessagePortChannel::MessagePortChannel(PassRefPtr<PlatformMessagePortChannel> channel) + : m_channel(channel) +{ +} + +MessagePortChannel::~MessagePortChannel() +{ + // Make sure we close our platform channel when the base is freed, to keep the channel objects from leaking. + m_channel->close(); +} + +bool MessagePortChannel::entangleIfOpen(MessagePort* port) +{ + return m_channel->entangleIfOpen(port); +} + +void MessagePortChannel::disentangle() +{ + m_channel->disentangle(); +} + +void MessagePortChannel::postMessageToRemote(PassOwnPtr<MessagePortChannel::EventData> message) +{ + m_channel->postMessageToRemote(message); +} + +bool MessagePortChannel::tryGetMessageFromRemote(OwnPtr<MessagePortChannel::EventData>& result) +{ + return m_channel->tryGetMessageFromRemote(result); +} + +void MessagePortChannel::close() +{ + m_channel->close(); +} + +bool MessagePortChannel::isConnectedTo(MessagePort* port) +{ + return m_channel->isConnectedTo(port); +} + +bool MessagePortChannel::hasPendingActivity() +{ + return m_channel->hasPendingActivity(); +} + +MessagePort* MessagePortChannel::locallyEntangledPort(const ScriptExecutionContext* context) +{ + // This is just an optimization, so return NULL always. + return NULL; +} + + +PassRefPtr<PlatformMessagePortChannel> PlatformMessagePortChannel::create() +{ + return adoptRef(new PlatformMessagePortChannel()); +} + +PassRefPtr<PlatformMessagePortChannel> PlatformMessagePortChannel::create( + WebMessagePortChannel* channel) +{ + return adoptRef(new PlatformMessagePortChannel(channel)); +} + + +PlatformMessagePortChannel::PlatformMessagePortChannel() + : m_localPort(0) +{ + m_webChannel = webKitClient()->createMessagePortChannel(); + m_webChannel->setClient(this); +} + +PlatformMessagePortChannel::PlatformMessagePortChannel(WebMessagePortChannel* channel) + : m_localPort(0) + , m_webChannel(channel) +{ +} + +PlatformMessagePortChannel::~PlatformMessagePortChannel() +{ + if (m_webChannel) + m_webChannel->destroy(); +} + +void PlatformMessagePortChannel::createChannel(PassRefPtr<MessagePort> port1, PassRefPtr<MessagePort> port2) +{ + // Create proxies for each endpoint. + RefPtr<PlatformMessagePortChannel> channel1 = PlatformMessagePortChannel::create(); + RefPtr<PlatformMessagePortChannel> channel2 = PlatformMessagePortChannel::create(); + + // Entangle the two endpoints. + channel1->setEntangledChannel(channel2); + channel2->setEntangledChannel(channel1); + + // Now entangle the proxies with the appropriate local ports. + port1->entangle(MessagePortChannel::create(channel2)); + port2->entangle(MessagePortChannel::create(channel1)); +} + +void PlatformMessagePortChannel::messageAvailable() +{ + MutexLocker lock(m_mutex); + if (m_localPort) + m_localPort->messageAvailable(); +} + +bool PlatformMessagePortChannel::entangleIfOpen(MessagePort* port) +{ + MutexLocker lock(m_mutex); + m_localPort = port; + return true; +} + +void PlatformMessagePortChannel::disentangle() +{ + MutexLocker lock(m_mutex); + m_localPort = 0; +} + +void PlatformMessagePortChannel::postMessageToRemote(PassOwnPtr<MessagePortChannel::EventData> message) +{ + if (!m_localPort) + return; + + WebString messageString = message->message(); + OwnPtr<WebCore::MessagePortChannel> channel = message->channel(); + WebMessagePortChannel* webChannel = NULL; + if (channel.get()) { + WebCore::PlatformMessagePortChannel* platformChannel = channel->channel(); + webChannel = platformChannel->webChannelRelease(); + webChannel->setClient(0); + } + m_webChannel->postMessage(messageString, webChannel); +} + +bool PlatformMessagePortChannel::tryGetMessageFromRemote(OwnPtr<MessagePortChannel::EventData>& result) +{ + if (!m_webChannel) + return false; + + WebString message; + WebMessagePortChannel* webChannel = NULL; + bool rv = m_webChannel->tryGetMessage(&message, &webChannel); + if (rv) { + OwnPtr<MessagePortChannel> channel; + if (webChannel) { + RefPtr<PlatformMessagePortChannel> platformChannel = create(webChannel); + webChannel->setClient(platformChannel.get()); + channel = MessagePortChannel::create(platformChannel); + } + result = MessagePortChannel::EventData::create(message, channel.release()); + } + + return rv; +} + +void PlatformMessagePortChannel::close() +{ + MutexLocker lock(m_mutex); + // Disentangle ourselves from the other end. We still maintain a reference to m_webChannel, + // since previously-existing messages should still be delivered. + m_localPort = 0; + m_entangledChannel = 0; +} + +bool PlatformMessagePortChannel::isConnectedTo(MessagePort* port) +{ + MutexLocker lock(m_mutex); + return m_entangledChannel && m_entangledChannel->m_localPort == port; +} + +bool PlatformMessagePortChannel::hasPendingActivity() +{ + MutexLocker lock(m_mutex); + return m_localPort; +} + +void PlatformMessagePortChannel::setEntangledChannel(PassRefPtr<PlatformMessagePortChannel> remote) +{ + m_webChannel->entangle(remote->m_webChannel); + + MutexLocker lock(m_mutex); + m_entangledChannel = remote; +} + +WebMessagePortChannel* PlatformMessagePortChannel::webChannelRelease() +{ + WebMessagePortChannel* rv = m_webChannel; + m_webChannel = 0; + return rv; +} + +} // namespace WebCore diff --git a/webkit/api/src/PlatformMessagePortChannel.h b/webkit/api/src/PlatformMessagePortChannel.h new file mode 100644 index 0000000..08c6a5c --- /dev/null +++ b/webkit/api/src/PlatformMessagePortChannel.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PlatformMessagePortChannel_h +#define PlatformMessagePortChannel_h + +#include "WebMessagePortChannelClient.h" + +#include "MessagePortChannel.h" + +#include <wtf/PassRefPtr.h> +#include <wtf/Threading.h> + +namespace WebKit { +class WebMessagePortChannel; +} + +namespace WebCore { + class MessagePort; + + // PlatformMessagePortChannel is a platform-dependent interface to the remote side of a message channel. + class PlatformMessagePortChannel : public ThreadSafeShared<PlatformMessagePortChannel>, + public WebKit::WebMessagePortChannelClient { + public: + static void createChannel(PassRefPtr<MessagePort>, PassRefPtr<MessagePort>); + static PassRefPtr<PlatformMessagePortChannel> create(); + static PassRefPtr<PlatformMessagePortChannel> create(WebKit::WebMessagePortChannel*); + + // APIs delegated from MessagePortChannel.h + bool entangleIfOpen(MessagePort*); + void disentangle(); + void postMessageToRemote(PassOwnPtr<MessagePortChannel::EventData>); + bool tryGetMessageFromRemote(OwnPtr<MessagePortChannel::EventData>&); + void close(); + bool isConnectedTo(MessagePort* port); + bool hasPendingActivity(); + + // Releases ownership of the contained web channel. + WebKit::WebMessagePortChannel* webChannelRelease(); + + ~PlatformMessagePortChannel(); + + private: + PlatformMessagePortChannel(); + PlatformMessagePortChannel(WebKit::WebMessagePortChannel*); + + void setEntangledChannel(PassRefPtr<PlatformMessagePortChannel>); + + // WebKit::WebMessagePortChannelClient implementation + virtual void messageAvailable(); + + // Mutex used to ensure exclusive access to the object internals. + Mutex m_mutex; + + // Pointer to our entangled pair - cleared when close() is called. + RefPtr<PlatformMessagePortChannel> m_entangledChannel; + + // The port we are connected to - this is the port that is notified when new messages arrive. + MessagePort* m_localPort; + + WebKit::WebMessagePortChannel* m_webChannel; + }; + +} // namespace WebCore + +#endif // PlatformMessagePortChannel_h diff --git a/webkit/tools/test_shell/test_shell_webkit_init.h b/webkit/tools/test_shell/test_shell_webkit_init.h index 0c64142..dbb8e81 100644 --- a/webkit/tools/test_shell/test_shell_webkit_init.h +++ b/webkit/tools/test_shell/test_shell_webkit_init.h @@ -89,6 +89,10 @@ class TestShellWebKitInit : public webkit_glue::WebKitClientImpl { return false; } + virtual WebKit::WebMessagePortChannel* createMessagePortChannel() { + return NULL; + } + virtual void setCookies(const WebKit::WebURL& url, const WebKit::WebURL& first_party_for_cookies, const WebKit::WebString& value) { diff --git a/webkit/tools/test_shell/test_worker/test_worker_main.cc b/webkit/tools/test_shell/test_worker/test_worker_main.cc index 30b52da..2739640 100644 --- a/webkit/tools/test_shell/test_worker/test_worker_main.cc +++ b/webkit/tools/test_shell/test_worker/test_worker_main.cc @@ -59,6 +59,10 @@ class WorkerWebKitClientImpl : public webkit_glue::WebKitClientImpl { return false; } + virtual WebKit::WebMessagePortChannel* createMessagePortChannel() { + return NULL; + } + virtual void setCookies(const WebKit::WebURL& url, const WebKit::WebURL& first_party_for_cookies, const WebKit::WebString& value) { diff --git a/webkit/webkit.gyp b/webkit/webkit.gyp index 85505ae..17531ce 100644 --- a/webkit/webkit.gyp +++ b/webkit/webkit.gyp @@ -706,6 +706,10 @@ '../third_party/WebKit/WebCore/platform/graphics/RenderLayerBacking.cpp', '../third_party/WebKit/WebCore/platform/graphics/RenderLayerCompositor.cpp', + # We use a multi-process version from the WebKit API. + '../third_party/WebKit/WebCore/dom/default/PlatformMessagePortChannel.cpp', + '../third_party/WebKit/WebCore/dom/default/PlatformMessagePortChannel.h', + ], 'direct_dependent_settings': { 'include_dirs': [ @@ -997,6 +1001,8 @@ 'api/public/WebLocalizedString.h', 'api/public/WebMediaPlayer.h', 'api/public/WebMediaPlayerClient.h', + 'api/public/WebMessagePortChannel.h', + 'api/public/WebMessagePortChannelClient.h', 'api/public/WebMimeRegistry.h', 'api/public/WebNavigationType.h', 'api/public/WebNode.h', @@ -1022,6 +1028,8 @@ 'api/public/WebVector.h', 'api/public/WebWidget.h', 'api/public/WebWidgetClient.h', + 'api/public/WebWorker.h', + 'api/public/WebWorkerClient.h', 'api/public/win/WebInputEventFactory.h', 'api/public/win/WebSandboxSupport.h', 'api/public/win/WebScreenInfoFactory.h', @@ -1038,6 +1046,8 @@ 'api/src/mac/WebScreenInfoFactory.mm', 'api/src/LocalizedStrings.cpp', 'api/src/MediaPlayerPrivateChromium.cpp', + 'api/src/PlatformMessagePortChannel.cpp', + 'api/src/PlatformMessagePortChannel.h', 'api/src/ResourceHandle.cpp', 'api/src/StorageAreaProxy.cpp', 'api/src/StorageAreaProxy.h', |