[EFL][WK2] Add RunLoopEfl and WorkQueueEfl
[WebKit-https.git] / Source / 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 "MessageID.h"
35 #include "WorkQueue.h"
36 #include <wtf/HashMap.h>
37 #include <wtf/PassRefPtr.h>
38 #include <wtf/OwnPtr.h>
39 #include <wtf/Threading.h>
40
41 #if OS(DARWIN)
42 #include <mach/mach_port.h>
43 #elif PLATFORM(WIN)
44 #include <string>
45 #elif PLATFORM(QT)
46 class QSocketNotifier;
47 #endif
48
49 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
50 #include "PlatformProcessIdentifier.h"
51 #endif
52
53 namespace WebCore {
54 class RunLoop;
55 }
56
57 namespace CoreIPC {
58
59 class BinarySemaphore;
60 class MessageID;
61     
62 enum MessageSendFlags {
63     // Whether this message should be dispatched when waiting for a sync reply.
64     // This is the default for synchronous messages.
65     DispatchMessageEvenWhenWaitingForSyncReply = 1 << 0,
66 };
67
68 enum SyncMessageSendFlags {
69     // Will allow events to continue being handled while waiting for the synch reply.
70     SpinRunLoopWhileWaitingForReply = 1 << 0,
71 };
72     
73 #define MESSAGE_CHECK_BASE(assertion, connection) do \
74     if (!(assertion)) { \
75         ASSERT(assertion); \
76         (connection)->markCurrentlyDispatchedMessageAsInvalid(); \
77         return; \
78     } \
79 while (0)
80
81 class Connection : public ThreadSafeRefCounted<Connection> {
82 public:
83     class MessageReceiver {
84     public:
85         virtual void didReceiveMessage(Connection*, MessageID, ArgumentDecoder*) = 0;
86         virtual void didReceiveSyncMessage(Connection*, MessageID, ArgumentDecoder*, OwnPtr<ArgumentEncoder>&) { ASSERT_NOT_REACHED(); }
87
88     protected:
89         virtual ~MessageReceiver() { }
90     };
91     
92     class Client : public MessageReceiver {
93     public:
94         virtual void didClose(Connection*) = 0;
95         virtual void didReceiveInvalidMessage(Connection*, MessageID) = 0;
96         virtual void syncMessageSendTimedOut(Connection*) = 0;
97
98 #if PLATFORM(WIN)
99         virtual Vector<HWND> windowsToReceiveSentMessagesWhileWaitingForSyncReply() = 0;
100 #endif
101
102     protected:
103         virtual ~Client() { }
104     };
105
106     class QueueClient {
107     public:
108         virtual void didReceiveMessageOnConnectionWorkQueue(Connection*, MessageID, ArgumentDecoder*, bool& didHandleMessage) = 0;
109
110     protected:
111         virtual ~QueueClient() { }
112     };
113
114 #if OS(DARWIN)
115     typedef mach_port_t Identifier;
116 #elif PLATFORM(WIN)
117     typedef HANDLE Identifier;
118     static bool createServerAndClientIdentifiers(Identifier& serverIdentifier, Identifier& clientIdentifier);
119 #elif USE(UNIX_DOMAIN_SOCKETS)
120     typedef int Identifier;
121 #endif
122
123     static PassRefPtr<Connection> createServerConnection(Identifier, Client*, WebCore::RunLoop* clientRunLoop);
124     static PassRefPtr<Connection> createClientConnection(Identifier, Client*, WebCore::RunLoop* clientRunLoop);
125     ~Connection();
126
127 #if OS(DARWIN)
128     void setShouldCloseConnectionOnMachExceptions();
129 #elif PLATFORM(QT)
130     void setShouldCloseConnectionOnProcessTermination(WebKit::PlatformProcessIdentifier);
131 #endif
132
133     void setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(bool);
134     void setShouldExitOnSyncMessageSendFailure(bool shouldExitOnSyncMessageSendFailure);
135
136     // The set callback will be called on the connection work queue when the connection is closed, 
137     // before didCall is called on the client thread. Must be called before the connection is opened.
138     // In the future we might want a more generic way to handle sync or async messages directly
139     // on the work queue, for example if we want to handle them on some other thread we could avoid
140     // handling the message on the client thread first.
141     typedef void (*DidCloseOnConnectionWorkQueueCallback)(WorkQueue&, Connection*);
142     void setDidCloseOnConnectionWorkQueueCallback(DidCloseOnConnectionWorkQueueCallback callback);
143
144     void addQueueClient(QueueClient*);
145     void removeQueueClient(QueueClient*);
146
147     bool open();
148     void invalidate();
149     void markCurrentlyDispatchedMessageAsInvalid();
150
151     void setDefaultSyncMessageTimeout(double);
152
153     void postConnectionDidCloseOnConnectionWorkQueue();
154
155     static const int DefaultTimeout = 0;
156     static const int NoTimeout = -1;
157
158     template<typename T> bool send(const T& message, uint64_t destinationID, unsigned messageSendFlags = 0);
159     template<typename T> bool sendSync(const T& message, const typename T::Reply& reply, uint64_t destinationID, double timeout = DefaultTimeout, unsigned syncSendFlags = 0);
160     template<typename T> bool waitForAndDispatchImmediately(uint64_t destinationID, double timeout);
161
162     PassOwnPtr<ArgumentEncoder> createSyncMessageArgumentEncoder(uint64_t destinationID, uint64_t& syncRequestID);
163     bool sendMessage(MessageID, PassOwnPtr<ArgumentEncoder>, unsigned messageSendFlags = 0);
164     bool sendSyncReply(PassOwnPtr<ArgumentEncoder>);
165
166     // FIXME: These variants of send, sendSync and waitFor are all deprecated.
167     // All clients should move to the overloads that take a message type.
168     template<typename E, typename T> bool deprecatedSend(E messageID, uint64_t destinationID, const T& arguments);
169     template<typename E, typename T, typename U> bool deprecatedSendSync(E messageID, uint64_t destinationID, const T& arguments, const U& reply, double timeout = NoTimeout);
170
171 private:
172     template<typename T> class Message {
173     public:
174         Message()
175             : m_arguments(0)
176         {
177         }
178
179         Message(MessageID messageID, PassOwnPtr<T> arguments)
180             : m_messageID(messageID)
181             , m_arguments(arguments.leakPtr())
182         {
183         }
184         
185         MessageID messageID() const { return m_messageID; }
186         uint64_t destinationID() const { return m_arguments->destinationID(); }
187
188         T* arguments() const { return m_arguments; }
189         
190         PassOwnPtr<T> releaseArguments()
191         {
192             OwnPtr<T> arguments = adoptPtr(m_arguments);
193             m_arguments = 0;
194
195             return arguments.release();
196         }
197         
198     private:
199         MessageID m_messageID;
200         // The memory management of this class is very unusual. The class acts
201         // as if it has an owning reference to m_arguments (e.g., accepting a
202         // PassOwnPtr in its constructor) in all ways except that it does not
203         // deallocate m_arguments on destruction.
204         // FIXME: Does this leak m_arguments on destruction?
205         T* m_arguments;
206     };
207
208 public:
209     typedef Message<ArgumentEncoder> OutgoingMessage;
210
211 private:
212     Connection(Identifier, bool isServer, Client*, WebCore::RunLoop* clientRunLoop);
213     void platformInitialize(Identifier);
214     void platformInvalidate();
215     
216     bool isValid() const { return m_client; }
217     
218     PassOwnPtr<ArgumentDecoder> waitForMessage(MessageID, uint64_t destinationID, double timeout);
219     
220     PassOwnPtr<ArgumentDecoder> sendSyncMessage(MessageID, uint64_t syncRequestID, PassOwnPtr<ArgumentEncoder>, double timeout, unsigned syncSendFlags = 0);
221     PassOwnPtr<ArgumentDecoder> waitForSyncReply(uint64_t syncRequestID, double timeout, unsigned syncSendFlags);
222
223     // Called on the connection work queue.
224     void processIncomingMessage(MessageID, PassOwnPtr<ArgumentDecoder>);
225     void processIncomingSyncReply(PassOwnPtr<ArgumentDecoder>);
226
227     void addQueueClientOnWorkQueue(QueueClient*);
228     void removeQueueClientOnWorkQueue(QueueClient*);
229     
230     bool canSendOutgoingMessages() const;
231     bool platformCanSendOutgoingMessages() const;
232     void sendOutgoingMessages();
233     bool sendOutgoingMessage(MessageID, PassOwnPtr<ArgumentEncoder>);
234     void connectionDidClose();
235     
236     typedef Message<ArgumentDecoder> IncomingMessage;
237
238     // Called on the listener thread.
239     void dispatchConnectionDidClose();
240     void dispatchMessage(IncomingMessage&);
241     void dispatchMessages();
242     void dispatchSyncMessage(MessageID, ArgumentDecoder*);
243     void didFailToSendSyncMessage();
244
245     // Can be called on any thread.
246     void enqueueIncomingMessage(IncomingMessage&);
247
248     Client* m_client;
249     bool m_isServer;
250     uint64_t m_syncRequestID;
251
252     bool m_onlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage;
253     bool m_shouldExitOnSyncMessageSendFailure;
254     DidCloseOnConnectionWorkQueueCallback m_didCloseOnConnectionWorkQueueCallback;
255
256     bool m_isConnected;
257     WorkQueue m_connectionQueue;
258     WebCore::RunLoop* m_clientRunLoop;
259
260     Vector<QueueClient*> m_connectionQueueClients;
261
262     unsigned m_inDispatchMessageCount;
263     unsigned m_inDispatchMessageMarkedDispatchWhenWaitingForSyncReplyCount;
264     bool m_didReceiveInvalidMessage;
265
266     double m_defaultSyncMessageTimeout;
267
268     // Incoming messages.
269     Mutex m_incomingMessagesLock;
270     Deque<IncomingMessage> m_incomingMessages;
271
272     // Outgoing messages.
273     Mutex m_outgoingMessagesLock;
274     Deque<OutgoingMessage> m_outgoingMessages;
275     
276     ThreadCondition m_waitForMessageCondition;
277     Mutex m_waitForMessageMutex;
278     HashMap<std::pair<unsigned, uint64_t>, ArgumentDecoder*> m_waitForMessageMap;
279
280     // Represents a sync request for which we're waiting on a reply.
281     struct PendingSyncReply {
282         // The request ID.
283         uint64_t syncRequestID;
284
285         // The reply decoder, will be null if there was an error processing the sync
286         // message on the other side.
287         ArgumentDecoder* replyDecoder;
288
289         // Will be set to true once a reply has been received or an error occurred.
290         bool didReceiveReply;
291     
292         PendingSyncReply()
293             : syncRequestID(0)
294             , replyDecoder(0)
295             , didReceiveReply(false)
296         {
297         }
298
299         explicit PendingSyncReply(uint64_t syncRequestID)
300             : syncRequestID(syncRequestID)
301             , replyDecoder(0)
302             , didReceiveReply(0)
303         {
304         }
305
306         PassOwnPtr<ArgumentDecoder> releaseReplyDecoder()
307         {
308             OwnPtr<ArgumentDecoder> reply = adoptPtr(replyDecoder);
309             replyDecoder = 0;
310             
311             return reply.release();
312         }
313     };
314     
315     class SyncMessageState;
316     friend class SyncMessageState;
317     RefPtr<SyncMessageState> m_syncMessageState;
318
319     Mutex m_syncReplyStateMutex;
320     bool m_shouldWaitForSyncReplies;
321     Vector<PendingSyncReply> m_pendingSyncReplies;
322
323 #if OS(DARWIN)
324     // Called on the connection queue.
325     void receiveSourceEventHandler();
326     void initializeDeadNameSource();
327     void exceptionSourceEventHandler();
328
329     mach_port_t m_sendPort;
330     mach_port_t m_receivePort;
331
332     // If setShouldCloseConnectionOnMachExceptions has been called, this has
333     // the exception port that exceptions from the other end will be sent on.
334     mach_port_t m_exceptionPort;
335
336 #elif PLATFORM(WIN)
337     // Called on the connection queue.
338     void readEventHandler();
339     void writeEventHandler();
340
341     // Called by Connection::SyncMessageState::waitWhileDispatchingSentWin32Messages.
342     // The absoluteTime is in seconds, starting on January 1, 1970. The time is assumed to use the
343     // same time zone as WTF::currentTime(). Dispatches sent (not posted) messages to the passed-in
344     // set of HWNDs until the semaphore is signaled or absoluteTime is reached. Returns true if the
345     // semaphore is signaled, false otherwise.
346     static bool dispatchSentMessagesUntil(const Vector<HWND>& windows, CoreIPC::BinarySemaphore& semaphore, double absoluteTime);
347
348     Vector<uint8_t> m_readBuffer;
349     OVERLAPPED m_readState;
350     OwnPtr<ArgumentEncoder> m_pendingWriteArguments;
351     OVERLAPPED m_writeState;
352     HANDLE m_connectionPipe;
353 #elif USE(UNIX_DOMAIN_SOCKETS)
354     // Called on the connection queue.
355     void readyReadHandler();
356     bool processMessage();
357
358     Vector<uint8_t> m_readBuffer;
359     size_t m_readBufferSize;
360     Vector<int> m_fileDescriptors;
361     size_t m_fileDescriptorsSize;
362     int m_socketDescriptor;
363 #if PLATFORM(QT)
364     QSocketNotifier* m_socketNotifier;
365 #endif
366 #endif
367 };
368
369 template<typename T> bool Connection::send(const T& message, uint64_t destinationID, unsigned messageSendFlags)
370 {
371     OwnPtr<ArgumentEncoder> argumentEncoder = ArgumentEncoder::create(destinationID);
372     argumentEncoder->encode(message);
373     
374     return sendMessage(MessageID(T::messageID), argumentEncoder.release(), messageSendFlags);
375 }
376
377 template<typename T> bool Connection::sendSync(const T& message, const typename T::Reply& reply, uint64_t destinationID, double timeout, unsigned syncSendFlags)
378 {
379     uint64_t syncRequestID = 0;
380     OwnPtr<ArgumentEncoder> argumentEncoder = createSyncMessageArgumentEncoder(destinationID, syncRequestID);
381     
382     // Encode the rest of the input arguments.
383     argumentEncoder->encode(message);
384
385     // Now send the message and wait for a reply.
386     OwnPtr<ArgumentDecoder> replyDecoder = sendSyncMessage(MessageID(T::messageID), syncRequestID, argumentEncoder.release(), timeout, syncSendFlags);
387     if (!replyDecoder)
388         return false;
389
390     // Decode the reply.
391     return replyDecoder->decode(const_cast<typename T::Reply&>(reply));
392 }
393
394 template<typename T> bool Connection::waitForAndDispatchImmediately(uint64_t destinationID, double timeout)
395 {
396     OwnPtr<ArgumentDecoder> decoder = waitForMessage(MessageID(T::messageID), destinationID, timeout);
397     if (!decoder)
398         return false;
399
400     ASSERT(decoder->destinationID() == destinationID);
401     m_client->didReceiveMessage(this, MessageID(T::messageID), decoder.get());
402     return true;
403 }
404
405 // These three member functions are all deprecated.
406
407 template<typename E, typename T, typename U>
408 inline bool Connection::deprecatedSendSync(E messageID, uint64_t destinationID, const T& arguments, const U& reply, double timeout)
409 {
410     uint64_t syncRequestID = 0;
411     OwnPtr<ArgumentEncoder> argumentEncoder = createSyncMessageArgumentEncoder(destinationID, syncRequestID);
412
413     // Encode the input arguments.
414     argumentEncoder->encode(arguments);
415     
416     // Now send the message and wait for a reply.
417     OwnPtr<ArgumentDecoder> replyDecoder = sendSyncMessage(MessageID(messageID), syncRequestID, argumentEncoder.release(), timeout);
418     if (!replyDecoder)
419         return false;
420     
421     // Decode the reply.
422     return replyDecoder->decode(const_cast<U&>(reply));
423 }
424
425 template<typename E, typename T>
426 bool Connection::deprecatedSend(E messageID, uint64_t destinationID, const T& arguments)
427 {
428     OwnPtr<ArgumentEncoder> argumentEncoder = ArgumentEncoder::create(destinationID);
429     argumentEncoder->encode(arguments);
430
431     return sendMessage(MessageID(messageID), argumentEncoder.release());
432 }
433
434 } // namespace CoreIPC
435
436 #endif // Connection_h