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 "AtomicStringHash.h"
31 #include "EventListener.h"
32 #include "EventTarget.h"
34 #include <wtf/HashMap.h>
35 #include <wtf/MessageQueue.h>
36 #include <wtf/PassRefPtr.h>
37 #include <wtf/RefPtr.h>
38 #include <wtf/Vector.h>
42 class AtomicStringImpl
;
45 class ScriptExecutionContext
;
49 class MessagePort
: public RefCounted
<MessagePort
>, public EventTarget
{
51 static PassRefPtr
<MessagePort
> create(ScriptExecutionContext
* scriptExecutionContext
) { return adoptRef(new MessagePort(scriptExecutionContext
)); }
54 PassRefPtr
<MessagePort
> clone(ExceptionCode
&); // Returns a port that isn't attached to any context.
56 bool active() const { return m_entangledPort
; }
57 void postMessage(const String
& message
, ExceptionCode
&);
58 void postMessage(const String
& message
, MessagePort
*, ExceptionCode
&);
59 PassRefPtr
<MessagePort
> startConversation(ScriptExecutionContext
*, const String
& message
);
63 bool queueIsOpen() const { return m_queueIsOpen
; }
65 MessagePort
* entangledPort() { return m_entangledPort
; }
66 static void entangle(MessagePort
*, MessagePort
*);
69 void contextDestroyed();
70 void attachToContext(ScriptExecutionContext
*);
71 virtual ScriptExecutionContext
* scriptExecutionContext() const;
73 virtual MessagePort
* toMessagePort() { return this; }
75 void queueCloseEvent();
76 void dispatchMessages();
78 virtual void addEventListener(const AtomicString
& eventType
, PassRefPtr
<EventListener
>, bool useCapture
);
79 virtual void removeEventListener(const AtomicString
& eventType
, EventListener
*, bool useCapture
);
80 virtual bool dispatchEvent(PassRefPtr
<Event
>, ExceptionCode
&);
82 typedef Vector
<RefPtr
<EventListener
> > ListenerVector
;
83 typedef HashMap
<AtomicString
, ListenerVector
> EventListenersMap
;
84 EventListenersMap
& eventListeners() { return m_eventListeners
; }
86 using RefCounted
<MessagePort
>::ref
;
87 using RefCounted
<MessagePort
>::deref
;
89 bool hasPendingActivity();
91 // FIXME: Per current spec, setting onmessage should automagically start the port (unlike addEventListener("message", ...)).
92 void setOnmessage(PassRefPtr
<EventListener
> eventListener
) { m_onMessageListener
= eventListener
; }
93 EventListener
* onmessage() const { return m_onMessageListener
.get(); }
95 void setOnclose(PassRefPtr
<EventListener
> eventListener
) { m_onCloseListener
= eventListener
; }
96 EventListener
* onclose() const { return m_onCloseListener
.get(); }
99 friend class MessagePortCloseEventTask
;
101 MessagePort(ScriptExecutionContext
*);
103 virtual void refEventTarget() { ref(); }
104 virtual void derefEventTarget() { deref(); }
106 void dispatchCloseEvent();
108 MessagePort
* m_entangledPort
;
110 // FIXME: EventData is necessary to pass messages to other threads. In single threaded case, we can just queue a created event.
111 struct EventData
: public RefCounted
<EventData
> {
112 static PassRefPtr
<EventData
> create(const String
& message
, PassRefPtr
<MessagePort
>);
116 RefPtr
<MessagePort
> messagePort
;
119 EventData(const String
& message
, PassRefPtr
<MessagePort
>);
121 MessageQueue
<RefPtr
<EventData
> > m_messageQueue
; // FIXME: No need to use MessageQueue in single threaded case.
124 ScriptExecutionContext
* m_scriptExecutionContext
;
126 RefPtr
<EventListener
> m_onMessageListener
;
127 RefPtr
<EventListener
> m_onCloseListener
;
129 EventListenersMap m_eventListeners
;
131 bool m_pendingCloseEvent
; // The port is GC protected while waiting for a close event to be dispatched.
134 } // namespace WebCore
136 #endif // MessagePort_h