WebProcess should be terminated if invalid frameIDs are
[WebKit-https.git] / WebKit2 / Platform / CoreIPC / Connection.h
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
4  * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25  * THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #ifndef Connection_h
29 #define Connection_h
30
31 #include "ArgumentDecoder.h"
32 #include "ArgumentEncoder.h"
33 #include "Arguments.h"
34 #include "BinarySemaphore.h"
35 #include "MessageID.h"
36 #include "WorkQueue.h"
37 #include <wtf/HashMap.h>
38 #include <wtf/PassRefPtr.h>
39 #include <wtf/OwnPtr.h>
40 #include <wtf/Threading.h>
41
42 #if PLATFORM(MAC)
43 #include <mach/mach_port.h>
44 #elif PLATFORM(WIN)
45 #include <string>
46 #elif PLATFORM(QT)
47 #include <QString>
48 class QLocalServer;
49 class QLocalSocket;
50 #endif
51
52 class RunLoop;
53
54 namespace CoreIPC {
55
56 class MessageID;
57     
58 enum SyncReplyMode {
59     AutomaticReply,
60     ManualReply
61 };
62
63 #define MESSAGE_CHECK_BASE(assertion, connection) do \
64     if (!(assertion)) { \
65         ASSERT(assertion); \
66         (connection)->markCurrentlyDispatchedMessageAsInvalid(); \
67         return; \
68     } \
69 while (0)
70
71 class Connection : public ThreadSafeShared<Connection> {
72 public:
73     class MessageReceiver {
74     protected:
75         virtual ~MessageReceiver() { }
76
77     public:
78         virtual void didReceiveMessage(Connection*, MessageID, ArgumentDecoder*) = 0;
79         virtual SyncReplyMode didReceiveSyncMessage(Connection*, MessageID, ArgumentDecoder*, ArgumentEncoder*) { ASSERT_NOT_REACHED(); return AutomaticReply; }
80     };
81     
82     class Client : public MessageReceiver {
83     protected:
84         virtual ~Client() { }
85
86     public:
87         virtual void didClose(Connection*) = 0;
88         virtual void didReceiveInvalidMessage(Connection*, MessageID) = 0;
89
90         // Called on the connection work queue when the connection is closed, before
91         // didCall is called on the client thread.
92         virtual void didCloseOnConnectionWorkQueue(WorkQueue*, Connection*) { }
93     };
94
95 #if PLATFORM(MAC)
96     typedef mach_port_t Identifier;
97 #elif PLATFORM(WIN)
98     typedef HANDLE Identifier;
99     static bool createServerAndClientIdentifiers(Identifier& serverIdentifier, Identifier& clientIdentifier);
100 #elif PLATFORM(QT)
101     typedef const QString Identifier;
102 #elif PLATFORM(GTK)
103     typedef int Identifier;
104 #endif
105
106     static PassRefPtr<Connection> createServerConnection(Identifier, Client*, RunLoop* clientRunLoop);
107     static PassRefPtr<Connection> createClientConnection(Identifier, Client*, RunLoop* clientRunLoop);
108     ~Connection();
109
110 #if PLATFORM(MAC)
111     void setShouldCloseConnectionOnMachExceptions();
112 #endif
113
114     bool open();
115     void invalidate();
116     void markCurrentlyDispatchedMessageAsInvalid();
117
118     // FIXME: This variant of send is deprecated, all clients should move to the overload that takes a message.
119     template<typename E, typename T> bool send(E messageID, uint64_t destinationID, const T& arguments);
120
121     template<typename T> bool send(const T& message, uint64_t destinationID);
122
123     static const unsigned long long NoTimeout = 10000000000ULL;
124     // FIXME: This variant of sendSync is deprecated, all clients should move to the overload that takes a message.
125     template<typename E, typename T, typename U> bool sendSync(E messageID, uint64_t destinationID, const T& arguments, const U& reply, double timeout = NoTimeout);
126
127     template<typename T> bool sendSync(const T& message, const typename T::Reply& reply, uint64_t destinationID, double timeout = NoTimeout);
128     
129     template<typename E> PassOwnPtr<ArgumentDecoder> waitFor(E messageID, uint64_t destinationID, double timeout);
130
131     PassOwnPtr<ArgumentEncoder> createSyncMessageArgumentEncoder(uint64_t destinationID, uint64_t& syncRequestID);
132     bool sendMessage(MessageID, PassOwnPtr<ArgumentEncoder>);
133     bool sendSyncReply(PassOwnPtr<ArgumentEncoder>);
134
135 private:
136     template<typename T> class Message {
137     public:
138         Message()
139             : m_arguments(0)
140         {
141         }
142
143         Message(MessageID messageID, PassOwnPtr<T> arguments)
144             : m_messageID(messageID)
145             , m_arguments(arguments.leakPtr())
146         {
147         }
148         
149         MessageID messageID() const { return m_messageID; }
150         T* arguments() const { return m_arguments; }
151         
152         PassOwnPtr<T> releaseArguments()
153         {
154             T* arguments = m_arguments;
155             m_arguments = 0;
156
157             return arguments;
158         }
159         
160     private:
161         MessageID m_messageID;
162         T* m_arguments;
163     };
164
165 public:
166     typedef Message<ArgumentEncoder> OutgoingMessage;
167
168 private:
169     Connection(Identifier, bool isServer, Client*, RunLoop* clientRunLoop);
170     void platformInitialize(Identifier);
171     void platformInvalidate();
172     
173     bool isValid() const { return m_client; }
174     
175     PassOwnPtr<ArgumentDecoder> waitForMessage(MessageID, uint64_t destinationID, double timeout);
176     
177     PassOwnPtr<ArgumentDecoder> sendSyncMessage(MessageID, uint64_t syncRequestID, PassOwnPtr<ArgumentEncoder>, double timeout);
178     PassOwnPtr<ArgumentDecoder> waitForSyncReply(uint64_t syncRequestID, double timeout);
179
180     // Called on the connection work queue.
181     void processIncomingMessage(MessageID, PassOwnPtr<ArgumentDecoder>);
182     bool canSendOutgoingMessages() const;
183     bool platformCanSendOutgoingMessages() const;
184     void sendOutgoingMessages();
185     bool sendOutgoingMessage(MessageID, PassOwnPtr<ArgumentEncoder>);
186     void connectionDidClose();
187     
188     // Called on the listener thread.
189     void dispatchConnectionDidClose();
190     void dispatchMessages();
191     void dispatchSyncMessage(MessageID, ArgumentDecoder*);
192                              
193     Client* m_client;
194     bool m_isServer;
195     uint64_t m_syncRequestID;
196
197     bool m_isConnected;
198     WorkQueue m_connectionQueue;
199     RunLoop* m_clientRunLoop;
200
201     uint32_t m_inDispatchMessageCount;
202     bool m_didReceiveInvalidMessage;
203
204     // Incoming messages.
205     typedef Message<ArgumentDecoder> IncomingMessage;
206
207     Mutex m_incomingMessagesLock;
208     Vector<IncomingMessage> m_incomingMessages;
209
210     // Outgoing messages.
211     Mutex m_outgoingMessagesLock;
212     Deque<OutgoingMessage> m_outgoingMessages;
213     
214     ThreadCondition m_waitForMessageCondition;
215     Mutex m_waitForMessageMutex;
216     HashMap<std::pair<unsigned, uint64_t>, ArgumentDecoder*> m_waitForMessageMap;
217
218     // Represents a sync request for which we're waiting on a reply.
219     struct PendingSyncReply {
220         // The request ID.
221         uint64_t syncRequestID;
222
223         // The reply decoder, will be null if there was an error processing the sync
224         // message on the other side.
225         ArgumentDecoder* replyDecoder;
226
227         // Will be set to true once a reply has been received or an error occurred.
228         bool didReceiveReply;
229     
230         PendingSyncReply()
231             : syncRequestID(0)
232             , replyDecoder(0)
233             , didReceiveReply(false)
234         {
235         }
236
237         explicit PendingSyncReply(uint64_t syncRequestID)
238             : syncRequestID(syncRequestID)
239             , replyDecoder(0)
240             , didReceiveReply(0)
241         {
242         }
243
244         PassOwnPtr<ArgumentDecoder> releaseReplyDecoder()
245         {
246             OwnPtr<ArgumentDecoder> reply = adoptPtr(replyDecoder);
247             replyDecoder = 0;
248             
249             return reply.release();
250         }
251     };
252     
253     BinarySemaphore m_waitForSyncReplySemaphore;
254
255     Mutex m_syncReplyStateMutex;
256     bool m_shouldWaitForSyncReplies;
257     Vector<PendingSyncReply> m_pendingSyncReplies;
258     Vector<IncomingMessage> m_syncMessagesReceivedWhileWaitingForSyncReply;
259
260 #if PLATFORM(MAC)
261     // Called on the connection queue.
262     void receiveSourceEventHandler();
263     void initializeDeadNameSource();
264     void exceptionSourceEventHandler();
265
266     mach_port_t m_sendPort;
267     mach_port_t m_receivePort;
268
269     // If setShouldCloseConnectionOnMachExceptions has been called, this has
270     // the exception port that exceptions from the other end will be sent on.
271     mach_port_t m_exceptionPort;
272
273 #elif PLATFORM(WIN)
274     // Called on the connection queue.
275     void readEventHandler();
276     void writeEventHandler();
277
278     Vector<uint8_t> m_readBuffer;
279     OVERLAPPED m_readState;
280     OwnPtr<ArgumentEncoder> m_pendingWriteArguments;
281     OVERLAPPED m_writeState;
282     HANDLE m_connectionPipe;
283 #elif PLATFORM(QT)
284     // Called on the connection queue.
285     void readyReadHandler();
286
287     Vector<uint8_t> m_readBuffer;
288     size_t m_currentMessageSize;
289     QLocalSocket* m_socket;
290     QString m_serverName;
291 #elif PLATFORM(GTK)
292     void readEventHandler();
293     void processCompletedMessage();
294     bool messageProcessingCompleted() { return !m_currentMessageSize; }
295
296     int m_socket;
297     Vector<uint8_t> m_readBuffer;
298     size_t m_currentMessageSize;
299     size_t m_pendingBytes;
300 #endif
301 };
302
303 template<typename E, typename T>
304 bool Connection::send(E messageID, uint64_t destinationID, const T& arguments)
305 {
306     OwnPtr<ArgumentEncoder> argumentEncoder = ArgumentEncoder::create(destinationID);
307     argumentEncoder->encode(arguments);
308
309     return sendMessage(MessageID(messageID), argumentEncoder.release());
310 }
311
312 template<typename T> bool Connection::send(const T& message, uint64_t destinationID)
313 {
314     OwnPtr<ArgumentEncoder> argumentEncoder = ArgumentEncoder::create(destinationID);
315     argumentEncoder->encode(message);
316     
317     return sendMessage(MessageID(T::messageID), argumentEncoder.release());
318 }
319
320 template<typename E, typename T, typename U>
321 inline bool Connection::sendSync(E messageID, uint64_t destinationID, const T& arguments, const U& reply, double timeout)
322 {
323     uint64_t syncRequestID = 0;
324     OwnPtr<ArgumentEncoder> argumentEncoder = createSyncMessageArgumentEncoder(destinationID, syncRequestID);
325
326     // Encode the input arguments.
327     argumentEncoder->encode(arguments);
328     
329     // Now send the message and wait for a reply.
330     OwnPtr<ArgumentDecoder> replyDecoder = sendSyncMessage(MessageID(messageID, MessageID::SyncMessage), syncRequestID, argumentEncoder.release(), timeout);
331     if (!replyDecoder)
332         return false;
333     
334     // Decode the reply.
335     return replyDecoder->decode(const_cast<U&>(reply));
336 }
337
338 template<typename T> bool Connection::sendSync(const T& message, const typename T::Reply& reply, uint64_t destinationID, double timeout)
339 {
340     uint64_t syncRequestID = 0;
341     OwnPtr<ArgumentEncoder> argumentEncoder = createSyncMessageArgumentEncoder(destinationID, syncRequestID);
342     
343     // Encode the rest of the input arguments.
344     argumentEncoder->encode(message);
345
346     // Now send the message and wait for a reply.
347     OwnPtr<ArgumentDecoder> replyDecoder = sendSyncMessage(MessageID(T::messageID, MessageID::SyncMessage), syncRequestID, argumentEncoder.release(), timeout);
348     if (!replyDecoder)
349         return false;
350
351     // Decode the reply.
352     return replyDecoder->decode(const_cast<typename T::Reply&>(reply));
353 }
354
355 template<typename E> inline PassOwnPtr<ArgumentDecoder> Connection::waitFor(E messageID, uint64_t destinationID, double timeout)
356 {
357     return waitForMessage(MessageID(messageID), destinationID, timeout);
358 }
359
360 } // namespace CoreIPC
361
362 #endif // Connection_h