• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
27 #ifndef MessagePort_h
28 #define MessagePort_h
29 
30 #include "AtomicStringHash.h"
31 #include "EventListener.h"
32 #include "EventTarget.h"
33 
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>
39 
40 namespace WebCore {
41 
42     class AtomicStringImpl;
43     class Event;
44     class Frame;
45     class ScriptExecutionContext;
46     class String;
47     class WorkerContext;
48 
49     class MessagePort : public RefCounted<MessagePort>, public EventTarget {
50     public:
create(ScriptExecutionContext * scriptExecutionContext)51         static PassRefPtr<MessagePort> create(ScriptExecutionContext* scriptExecutionContext) { return adoptRef(new MessagePort(scriptExecutionContext)); }
52         ~MessagePort();
53 
54         PassRefPtr<MessagePort> clone(ExceptionCode&); // Returns a port that isn't attached to any context.
55 
active()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);
60         void start();
61         void close();
62 
queueIsOpen()63         bool queueIsOpen() const { return m_queueIsOpen; }
64 
entangledPort()65         MessagePort* entangledPort() { return m_entangledPort; }
66         static void entangle(MessagePort*, MessagePort*);
67         void unentangle();
68 
69         void contextDestroyed();
70         void attachToContext(ScriptExecutionContext*);
71         virtual ScriptExecutionContext* scriptExecutionContext() const;
72 
toMessagePort()73         virtual MessagePort* toMessagePort() { return this; }
74 
75         void queueCloseEvent();
76         void dispatchMessages();
77 
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&);
81 
82         typedef Vector<RefPtr<EventListener> > ListenerVector;
83         typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
eventListeners()84         EventListenersMap& eventListeners() { return m_eventListeners; }
85 
86         using RefCounted<MessagePort>::ref;
87         using RefCounted<MessagePort>::deref;
88 
89         bool hasPendingActivity();
90 
91         // FIXME: Per current spec, setting onmessage should automagically start the port (unlike addEventListener("message", ...)).
setOnmessage(PassRefPtr<EventListener> eventListener)92         void setOnmessage(PassRefPtr<EventListener> eventListener) { m_onMessageListener = eventListener; }
onmessage()93         EventListener* onmessage() const { return m_onMessageListener.get(); }
94 
setOnclose(PassRefPtr<EventListener> eventListener)95         void setOnclose(PassRefPtr<EventListener> eventListener) { m_onCloseListener = eventListener; }
onclose()96         EventListener* onclose() const { return m_onCloseListener.get(); }
97 
98     private:
99         friend class MessagePortCloseEventTask;
100 
101         MessagePort(ScriptExecutionContext*);
102 
refEventTarget()103         virtual void refEventTarget() { ref(); }
derefEventTarget()104         virtual void derefEventTarget() { deref(); }
105 
106         void dispatchCloseEvent();
107 
108         MessagePort* m_entangledPort;
109 
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>);
113             ~EventData();
114 
115             String message;
116             RefPtr<MessagePort> messagePort;
117 
118         private:
119             EventData(const String& message, PassRefPtr<MessagePort>);
120         };
121         MessageQueue<RefPtr<EventData> > m_messageQueue; // FIXME: No need to use MessageQueue in single threaded case.
122         bool m_queueIsOpen;
123 
124         ScriptExecutionContext* m_scriptExecutionContext;
125 
126         RefPtr<EventListener> m_onMessageListener;
127         RefPtr<EventListener> m_onCloseListener;
128 
129         EventListenersMap m_eventListeners;
130 
131         bool m_pendingCloseEvent; // The port is GC protected while waiting for a close event to be dispatched.
132     };
133 
134 } // namespace WebCore
135 
136 #endif // MessagePort_h
137