blob: 337e22512407462f15e6b875f8f5c7301ad41189 [file] [log] [blame]
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001/*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Ben Murdoch02772c62013-07-26 10:21:05 +010023 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010024 *
25 */
26
27#ifndef MessagePort_h
28#define MessagePort_h
29
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010030#include "bindings/v8/ScriptWrappable.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010031#include "core/dom/EventListener.h"
32#include "core/dom/EventTarget.h"
33#include "core/dom/MessagePortChannel.h"
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010034#include "wtf/Forward.h"
35#include "wtf/OwnPtr.h"
36#include "wtf/PassOwnPtr.h"
37#include "wtf/PassRefPtr.h"
38#include "wtf/RefPtr.h"
39#include "wtf/Vector.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010040
41namespace WebCore {
42
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010043class Event;
Ben Murdoch7757ec22013-07-23 11:17:36 +010044class ExceptionState;
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010045class Frame;
46class MessagePort;
47class ScriptExecutionContext;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010048
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010049// The overwhelmingly common case is sending a single port, so handle that efficiently with an inline buffer of size 1.
50typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010051
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010052class MessagePort : public RefCounted<MessagePort>, public ScriptWrappable, public EventTarget {
53public:
54 static PassRefPtr<MessagePort> create(ScriptExecutionContext& scriptExecutionContext) { return adoptRef(new MessagePort(scriptExecutionContext)); }
55 virtual ~MessagePort();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010056
Ben Murdoch7757ec22013-07-23 11:17:36 +010057 void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, ExceptionState&);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010058
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010059 void start();
60 void close();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010061
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010062 void entangle(PassOwnPtr<MessagePortChannel>);
63 PassOwnPtr<MessagePortChannel> disentangle();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010064
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010065 // Returns 0 if there is an exception, or if the passed-in array is 0/empty.
Ben Murdoch7757ec22013-07-23 11:17:36 +010066 static PassOwnPtr<MessagePortChannelArray> disentanglePorts(const MessagePortArray*, ExceptionState&);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010067
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010068 // Returns 0 if the passed array is 0/empty.
69 static PassOwnPtr<MessagePortArray> entanglePorts(ScriptExecutionContext&, PassOwnPtr<MessagePortChannelArray>);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010070
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010071 void messageAvailable();
72 bool started() const { return m_started; }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010073
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010074 void contextDestroyed();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010075
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010076 virtual const AtomicString& interfaceName() const OVERRIDE;
77 virtual ScriptExecutionContext* scriptExecutionContext() const OVERRIDE;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010078
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010079 void dispatchMessages();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010080
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010081 using RefCounted<MessagePort>::ref;
82 using RefCounted<MessagePort>::deref;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010083
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010084 bool hasPendingActivity();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010085
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +010086 void setOnmessage(PassRefPtr<EventListener> listener, DOMWrapperWorld* world)
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010087 {
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +010088 setAttributeEventListener(eventNames().messageEvent, listener, world);
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010089 start();
90 }
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +010091 EventListener* onmessage(DOMWrapperWorld* world) { return getAttributeEventListener(eventNames().messageEvent, world); }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010092
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010093 // Returns null if there is no entangled port, or if the entangled port is run by a different thread.
94 // This is used solely to enable a GC optimization. Some platforms may not be able to determine ownership
95 // of the remote port (since it may live cross-process) - those platforms may always return null.
96 MessagePort* locallyEntangledPort();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010097
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010098 // A port starts out its life entangled, and remains entangled until it is closed or is cloned.
99 bool isEntangled() { return !m_closed && !isNeutered(); }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100100
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100101 // A port gets neutered when it is transferred to a new owner via postMessage().
102 bool isNeutered() { return !m_entangledChannel; }
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100103
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100104private:
105 explicit MessagePort(ScriptExecutionContext&);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100106
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100107 virtual void refEventTarget() OVERRIDE { ref(); }
108 virtual void derefEventTarget() OVERRIDE { deref(); }
109 virtual EventTargetData* eventTargetData() OVERRIDE;
110 virtual EventTargetData* ensureEventTargetData() OVERRIDE;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100111
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100112 OwnPtr<MessagePortChannel> m_entangledChannel;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100113
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100114 bool m_started;
115 bool m_closed;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100116
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100117 ScriptExecutionContext* m_scriptExecutionContext;
118 EventTargetData m_eventTargetData;
119};
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100120
121} // namespace WebCore
122
123#endif // MessagePort_h