Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef mozilla_dom_MessagePort_h
8 : #define mozilla_dom_MessagePort_h
9 :
10 : #include "mozilla/Attributes.h"
11 : #include "mozilla/DOMEventTargetHelper.h"
12 : #include "nsAutoPtr.h"
13 : #include "nsIIPCBackgroundChildCreateCallback.h"
14 : #include "nsTArray.h"
15 :
16 : #ifdef XP_WIN
17 : #undef PostMessage
18 : #endif
19 :
20 : class nsIGlobalObject;
21 :
22 : namespace mozilla {
23 : namespace dom {
24 :
25 : class ClonedMessageData;
26 : class MessagePortChild;
27 : class MessagePortIdentifier;
28 : class PostMessageRunnable;
29 : class SharedMessagePortMessage;
30 :
31 : namespace workers {
32 : class WorkerHolder;
33 : } // namespace workers
34 :
35 : class MessagePort final : public DOMEventTargetHelper
36 : , public nsIIPCBackgroundChildCreateCallback
37 : , public nsIObserver
38 : {
39 : friend class PostMessageRunnable;
40 :
41 : public:
42 : NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
43 : NS_DECL_NSIOBSERVER
44 : NS_DECL_ISUPPORTS_INHERITED
45 0 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MessagePort,
46 : DOMEventTargetHelper)
47 :
48 : static already_AddRefed<MessagePort>
49 : Create(nsIGlobalObject* aGlobal, const nsID& aUUID,
50 : const nsID& aDestinationUUID, ErrorResult& aRv);
51 :
52 : static already_AddRefed<MessagePort>
53 : Create(nsIGlobalObject* aGlobal,
54 : const MessagePortIdentifier& aIdentifier,
55 : ErrorResult& aRv);
56 :
57 : // For IPC.
58 : static void
59 : ForceClose(const MessagePortIdentifier& aIdentifier);
60 :
61 : virtual JSObject*
62 : WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
63 :
64 : void
65 : PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
66 : const Sequence<JSObject*>& aTransferable,
67 : ErrorResult& aRv);
68 :
69 : void Start();
70 :
71 : void Close();
72 :
73 : EventHandlerNonNull* GetOnmessage();
74 :
75 : void SetOnmessage(EventHandlerNonNull* aCallback);
76 :
77 : // Non WebIDL methods
78 :
79 : void UnshippedEntangle(MessagePort* aEntangledPort);
80 :
81 : void CloneAndDisentangle(MessagePortIdentifier& aIdentifier);
82 :
83 : void CloseForced();
84 :
85 : // These methods are useful for MessagePortChild
86 :
87 : void Entangled(nsTArray<ClonedMessageData>& aMessages);
88 : void MessagesReceived(nsTArray<ClonedMessageData>& aMessages);
89 : void StopSendingDataConfirmed();
90 : void Closed();
91 :
92 : private:
93 : explicit MessagePort(nsIGlobalObject* aGlobal);
94 : ~MessagePort();
95 :
96 : enum State {
97 : // When a port is created by a MessageChannel it is entangled with the
98 : // other. They both run on the same thread, same event loop and the
99 : // messages are added to the queues without using PBackground actors.
100 : // When one of the port is shipped, the state is changed to
101 : // StateEntangling.
102 : eStateUnshippedEntangled,
103 :
104 : // If the port is closed or cloned when we are in this state, we go in one
105 : // of the following 2 steps. EntanglingForClose or ForDisentangle.
106 : eStateEntangling,
107 :
108 : // We are not fully entangled yet but are already disentangled.
109 : eStateEntanglingForDisentangle,
110 :
111 : // We are not fully entangled yet but are already closed.
112 : eStateEntanglingForClose,
113 :
114 : // When entangled() is received we send all the messages in the
115 : // mMessagesForTheOtherPort to the actor and we change the state to
116 : // StateEntangled. At this point the port is entangled with the other. We
117 : // send and receive messages.
118 : // If the port queue is not enabled, the received messages are stored in
119 : // the mMessages.
120 : eStateEntangled,
121 :
122 : // When the port is cloned or disentangled we want to stop receiving
123 : // messages. We call 'SendStopSendingData' to the actor and we wait for an
124 : // answer. All the messages received between now and the
125 : // 'StopSendingDataComfirmed are queued in the mMessages but not
126 : // dispatched.
127 : eStateDisentangling,
128 :
129 : // When 'StopSendingDataConfirmed' is received, we can disentangle the port
130 : // calling SendDisentangle in the actor because we are 100% sure that we
131 : // don't receive any other message, so nothing will be lost.
132 : // Disentangling the port we send all the messages from the mMessages
133 : // though the actor.
134 : eStateDisentangled,
135 :
136 : // We are here if Close() has been called. We are disentangled but we can
137 : // still send pending messages.
138 : eStateDisentangledForClose
139 : };
140 :
141 : void Initialize(const nsID& aUUID, const nsID& aDestinationUUID,
142 : uint32_t aSequenceID, bool mNeutered, State aState,
143 : ErrorResult& aRv);
144 :
145 : void ConnectToPBackground();
146 :
147 : // Dispatch events from the Message Queue using a nsRunnable.
148 : void Dispatch();
149 :
150 : void StartDisentangling();
151 : void Disentangle();
152 :
153 : void RemoveDocFromBFCache();
154 :
155 : void CloseInternal(bool aSoftly);
156 :
157 : // This method is meant to keep alive the MessagePort when this object is
158 : // creating the actor and until the actor is entangled.
159 : // We release the object when the port is closed or disentangled.
160 : void UpdateMustKeepAlive();
161 :
162 0 : bool IsCertainlyAliveForCC() const override
163 : {
164 0 : return mIsKeptAlive;
165 : }
166 :
167 : nsAutoPtr<workers::WorkerHolder> mWorkerHolder;
168 :
169 : RefPtr<PostMessageRunnable> mPostMessageRunnable;
170 :
171 : RefPtr<MessagePortChild> mActor;
172 :
173 : RefPtr<MessagePort> mUnshippedEntangledPort;
174 :
175 : nsTArray<RefPtr<SharedMessagePortMessage>> mMessages;
176 : nsTArray<RefPtr<SharedMessagePortMessage>> mMessagesForTheOtherPort;
177 :
178 : nsAutoPtr<MessagePortIdentifier> mIdentifier;
179 :
180 : uint64_t mInnerID;
181 :
182 : State mState;
183 :
184 : bool mMessageQueueEnabled;
185 :
186 : bool mIsKeptAlive;
187 : };
188 :
189 : } // namespace dom
190 : } // namespace mozilla
191 :
192 : #endif // mozilla_dom_MessagePort_h
|