2
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
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.
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
23
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
#include "EventListener.h"
31
#include "EventTarget.h"
32
#include "MessagePortChannel.h"
33
#include <wtf/Forward.h>
34
#include <wtf/OwnPtr.h>
35
#include <wtf/PassOwnPtr.h>
36
#include <wtf/PassRefPtr.h>
37
#include <wtf/RefPtr.h>
38
#include <wtf/Vector.h>
39
#include <wtf/text/AtomicStringHash.h>
46
class ScriptExecutionContext;
48
// The overwhelmingly common case is sending a single port, so handle that efficiently with an inline buffer of size 1.
49
typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
51
// FIXME: This class should inherit from ActiveDOMObject and use
52
// setPendingActivity / unsetPendingActivity instead of duplicating
53
// ActiveDOMObject's features and relying on JavaScript garbage collection
54
// to get its lifetime right.
55
class MessagePort : public RefCounted<MessagePort>, public EventTarget {
57
static PassRefPtr<MessagePort> create(ScriptExecutionContext& scriptExecutionContext) { return adoptRef(new MessagePort(scriptExecutionContext)); }
60
void postMessage(PassRefPtr<SerializedScriptValue> message, ExceptionCode&);
61
void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, ExceptionCode&);
62
// FIXME: remove this when we update the ObjC bindings (bug #28774).
63
void postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort*, ExceptionCode&);
68
void entangle(PassOwnPtr<MessagePortChannel>);
69
PassOwnPtr<MessagePortChannel> disentangle(ExceptionCode&);
71
// Disentangle an array of ports, returning the entangled channels.
72
// Per section 8.3.3 of the HTML5 spec, generates an INVALID_STATE_ERR exception if any of the passed ports are null or not entangled.
73
// Returns 0 if there is an exception, or if the passed-in array is 0/empty.
74
static PassOwnPtr<MessagePortChannelArray> disentanglePorts(const MessagePortArray*, ExceptionCode&);
76
// Entangles an array of channels, returning an array of MessagePorts in matching order.
77
// Returns 0 if the passed array is 0/empty.
78
static PassOwnPtr<MessagePortArray> entanglePorts(ScriptExecutionContext&, PassOwnPtr<MessagePortChannelArray>);
80
void messageAvailable();
81
bool started() const { return m_started; }
83
void contextDestroyed();
85
virtual const AtomicString& interfaceName() const;
86
virtual ScriptExecutionContext* scriptExecutionContext() const;
88
void dispatchMessages();
90
using RefCounted<MessagePort>::ref;
91
using RefCounted<MessagePort>::deref;
93
bool hasPendingActivity();
95
void setOnmessage(PassRefPtr<EventListener> listener)
97
setAttributeEventListener(eventNames().messageEvent, listener);
100
EventListener* onmessage() { return getAttributeEventListener(eventNames().messageEvent); }
102
// Returns null if there is no entangled port, or if the entangled port is run by a different thread.
103
// Returns null otherwise.
104
// NOTE: This is used solely to enable a GC optimization. Some platforms may not be able to determine ownership of the remote port (since it may live cross-process) - those platforms may always return null.
105
MessagePort* locallyEntangledPort();
106
// A port starts out its life entangled, and remains entangled until it is closed or is cloned.
107
bool isEntangled() { return !m_closed && !isCloned(); }
108
// A port is cloned if its entangled channel has been removed and sent to a new owner via postMessage().
109
bool isCloned() { return !m_entangledChannel; }
112
explicit MessagePort(ScriptExecutionContext&);
114
virtual void refEventTarget() { ref(); }
115
virtual void derefEventTarget() { deref(); }
116
virtual EventTargetData* eventTargetData();
117
virtual EventTargetData* ensureEventTargetData();
119
OwnPtr<MessagePortChannel> m_entangledChannel;
124
ScriptExecutionContext* m_scriptExecutionContext;
125
EventTargetData m_eventTargetData;
128
} // namespace WebCore
130
#endif // MessagePort_h