~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/webkit/WebCore/dom/MessagePort.h

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2009-11-02 18:30:08 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (15.2.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 88.
  • Revision ID: james.westby@ubuntu.com-20091102183008-b6a4gcs128mvfb3m
Tags: upstream-4.6.0~beta1
ImportĀ upstreamĀ versionĀ 4.6.0~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 
30
30
#include "AtomicStringHash.h"
31
31
#include "EventListener.h"
 
32
#include "EventNames.h"
32
33
#include "EventTarget.h"
33
 
 
 
34
#include "MessagePortChannel.h"
34
35
#include <wtf/HashMap.h>
35
 
#include <wtf/MessageQueue.h>
 
36
#include <wtf/OwnPtr.h>
 
37
#include <wtf/PassOwnPtr.h>
36
38
#include <wtf/PassRefPtr.h>
37
39
#include <wtf/RefPtr.h>
38
40
#include <wtf/Vector.h>
42
44
    class AtomicStringImpl;
43
45
    class Event;
44
46
    class Frame;
 
47
    class MessagePort;
45
48
    class ScriptExecutionContext;
46
49
    class String;
47
 
    class WorkerContext;
 
50
 
 
51
    // The overwhelmingly common case is sending a single port, so handle that efficiently with an inline buffer of size 1.
 
52
    typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
48
53
 
49
54
    class MessagePort : public RefCounted<MessagePort>, public EventTarget {
50
55
    public:
51
 
        static PassRefPtr<MessagePort> create(ScriptExecutionContext* scriptExecutionContext) { return adoptRef(new MessagePort(scriptExecutionContext)); }
 
56
        static PassRefPtr<MessagePort> create(ScriptExecutionContext& scriptExecutionContext) { return adoptRef(new MessagePort(scriptExecutionContext)); }
52
57
        ~MessagePort();
53
58
 
54
 
        PassRefPtr<MessagePort> clone(ExceptionCode&); // Returns a port that isn't attached to any context.
55
 
 
56
 
        bool active() const { return m_entangledPort; }
57
59
        void postMessage(const String& message, ExceptionCode&);
 
60
        void postMessage(const String& message, const MessagePortArray*, ExceptionCode&);
 
61
        // FIXME: remove this when we update the ObjC bindings (bug #28774).
58
62
        void postMessage(const String& message, MessagePort*, ExceptionCode&);
59
 
        PassRefPtr<MessagePort> startConversation(ScriptExecutionContext*, const String& message);
 
63
 
60
64
        void start();
61
65
        void close();
62
66
 
63
 
        bool queueIsOpen() const { return m_queueIsOpen; }
64
 
 
65
 
        MessagePort* entangledPort() { return m_entangledPort; }
66
 
        static void entangle(MessagePort*, MessagePort*);
67
 
        void unentangle();
 
67
        void entangle(PassOwnPtr<MessagePortChannel>);
 
68
        PassOwnPtr<MessagePortChannel> disentangle(ExceptionCode&);
 
69
 
 
70
        // Disentangle an array of ports, returning the entangled channels.
 
71
        // 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.
 
72
        // Returns 0 if there is an exception, or if the passed-in array is 0/empty.
 
73
        static PassOwnPtr<MessagePortChannelArray> disentanglePorts(const MessagePortArray*, ExceptionCode&);
 
74
 
 
75
        // Entangles an array of channels, returning an array of MessagePorts in matching order.
 
76
        // Returns 0 if the passed array is 0/empty.
 
77
        static PassOwnPtr<MessagePortArray> entanglePorts(ScriptExecutionContext&, PassOwnPtr<MessagePortChannelArray>);
 
78
 
 
79
        void messageAvailable();
 
80
        bool started() const { return m_started; }
68
81
 
69
82
        void contextDestroyed();
70
 
        void attachToContext(ScriptExecutionContext*);
 
83
 
71
84
        virtual ScriptExecutionContext* scriptExecutionContext() const;
72
85
 
73
86
        virtual MessagePort* toMessagePort() { return this; }
74
87
 
75
 
        void queueCloseEvent();
76
88
        void dispatchMessages();
77
89
 
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;
84
 
        EventListenersMap& eventListeners() { return m_eventListeners; }
85
 
 
86
90
        using RefCounted<MessagePort>::ref;
87
91
        using RefCounted<MessagePort>::deref;
88
92
 
89
93
        bool hasPendingActivity();
90
94
 
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 setOnmessage(PassRefPtr<EventListener> listener)
 
96
        {
 
97
            setAttributeEventListener(eventNames().messageEvent, listener);
 
98
            start();
 
99
        }
 
100
        EventListener* onmessage() { return getAttributeEventListener(eventNames().messageEvent); }
94
101
 
95
 
        void setOnclose(PassRefPtr<EventListener> eventListener) { m_onCloseListener = eventListener; }
96
 
        EventListener* onclose() const { return m_onCloseListener.get(); }
 
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
        bool isEntangled() { return m_entangledChannel; }
97
107
 
98
108
    private:
99
 
        friend class MessagePortCloseEventTask;
100
 
 
101
 
        MessagePort(ScriptExecutionContext*);
 
109
        MessagePort(ScriptExecutionContext&);
102
110
 
103
111
        virtual void refEventTarget() { ref(); }
104
112
        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;
 
113
        virtual EventTargetData* eventTargetData();
 
114
        virtual EventTargetData* ensureEventTargetData();
 
115
 
 
116
        OwnPtr<MessagePortChannel> m_entangledChannel;
 
117
 
 
118
        bool m_started;
123
119
 
124
120
        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.
 
121
        EventTargetData m_eventTargetData;
132
122
    };
133
123
 
134
124
} // namespace WebCore