[EFL][WK2] Add RunLoopEfl and WorkQueueEfl
[WebKit-https.git] / Source / WebKit2 / Platform / WorkQueue.h
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #ifndef WorkQueue_h
28 #define WorkQueue_h
29
30 #if OS(DARWIN)
31 #if HAVE(DISPATCH_H)
32 #include <dispatch/dispatch.h>
33 #endif
34 #endif
35
36 #include <wtf/Forward.h>
37 #include <wtf/Functional.h>
38 #include <wtf/HashMap.h>
39 #include <wtf/PassOwnPtr.h>
40 #include <wtf/RefCounted.h>
41 #include <wtf/Threading.h>
42 #include <wtf/Vector.h>
43
44 #if (PLATFORM(QT) && !OS(DARWIN)) || PLATFORM(GTK) || PLATFORM(EFL)
45 #include "PlatformProcessIdentifier.h"
46 #endif
47
48 #if PLATFORM(QT) && !OS(DARWIN)
49 #include <QSocketNotifier>
50 class QObject;
51 class QThread;
52 #elif PLATFORM(GTK)
53 #include <wtf/gobject/GRefPtr.h>
54 typedef gboolean (*GSourceFunc) (gpointer data);
55 #elif PLATFORM(EFL)
56 #include <Ecore.h>
57 #endif
58
59 class WorkQueue {
60     WTF_MAKE_NONCOPYABLE(WorkQueue);
61
62 public:
63     explicit WorkQueue(const char* name);
64     ~WorkQueue();
65
66     // Will dispatch the given function to run as soon as possible.
67     void dispatch(const Function<void()>&);
68
69     // Will dispatch the given function after the given delay (in seconds).
70     void dispatchAfterDelay(const Function<void()>&, double delay);
71
72     void invalidate();
73
74 #if OS(DARWIN)
75     enum MachPortEventType {
76         // Fired when there is data on the given receive right.
77         MachPortDataAvailable,
78         
79         // Fired when the receive right for this send right has been destroyed.
80         MachPortDeadNameNotification
81     };
82     
83     // Will execute the given function whenever the given mach port event fires.
84     // Note that this will adopt the mach port and destroy it when the work queue is invalidated.
85     void registerMachPortEventHandler(mach_port_t, MachPortEventType, const Function<void()>&);
86     void unregisterMachPortEventHandler(mach_port_t);
87 #elif PLATFORM(WIN)
88     void registerHandle(HANDLE, const Function<void()>&);
89     void unregisterAndCloseHandle(HANDLE);
90 #elif PLATFORM(QT)
91     QSocketNotifier* registerSocketEventHandler(int, QSocketNotifier::Type, const Function<void()>&);
92     void dispatchOnTermination(WebKit::PlatformProcessIdentifier, const Function<void()>&);
93 #elif PLATFORM(GTK)
94     void registerEventSourceHandler(int, int, const Function<void()>&);
95     void unregisterEventSourceHandler(int);
96     void dispatchOnTermination(WebKit::PlatformProcessIdentifier, const Function<void()>&);
97 #elif PLATFORM(EFL)
98     void registerSocketEventHandler(int, const Function<void()>&);
99     void unregisterSocketEventHandler(int);
100 #endif
101
102 private:
103     // FIXME: Use an atomic boolean here instead.
104     Mutex m_isValidMutex;
105     bool m_isValid;
106
107     void platformInitialize(const char* name);
108     void platformInvalidate();
109
110 #if OS(DARWIN)
111 #if HAVE(DISPATCH_H)
112     static void executeFunction(void*);
113     Mutex m_eventSourcesMutex;
114     class EventSource;
115     HashMap<mach_port_t, EventSource*> m_eventSources;
116     dispatch_queue_t m_dispatchQueue;
117 #endif
118 #elif PLATFORM(WIN)
119     class WorkItemWin : public ThreadSafeRefCounted<WorkItemWin> {
120     public:
121         static PassRefPtr<WorkItemWin> create(const Function<void()>&, WorkQueue*);
122         virtual ~WorkItemWin();
123
124         Function<void()>& function() { return m_function; }
125         WorkQueue* queue() const { return m_queue; }
126
127     protected:
128         WorkItemWin(const Function<void()>&, WorkQueue*);
129
130     private:
131         Function<void()> m_function;
132         WorkQueue* m_queue;
133     };
134
135     class HandleWorkItem : public WorkItemWin {
136     public:
137         static PassRefPtr<HandleWorkItem> createByAdoptingHandle(HANDLE, const Function<void()>&, WorkQueue*);
138         virtual ~HandleWorkItem();
139
140         void setWaitHandle(HANDLE waitHandle) { m_waitHandle = waitHandle; }
141         HANDLE waitHandle() const { return m_waitHandle; }
142
143     private:
144         HandleWorkItem(HANDLE, const Function<void()>&, WorkQueue*);
145
146         HANDLE m_handle;
147         HANDLE m_waitHandle;
148     };
149
150     static void CALLBACK handleCallback(void* context, BOOLEAN timerOrWaitFired);
151     static void CALLBACK timerCallback(void* context, BOOLEAN timerOrWaitFired);
152     static DWORD WINAPI workThreadCallback(void* context);
153
154     bool tryRegisterAsWorkThread();
155     void unregisterAsWorkThread();
156     void performWorkOnRegisteredWorkThread();
157
158     static void unregisterWaitAndDestroyItemSoon(PassRefPtr<HandleWorkItem>);
159     static DWORD WINAPI unregisterWaitAndDestroyItemCallback(void* context);
160
161     volatile LONG m_isWorkThreadRegistered;
162
163     Mutex m_workItemQueueLock;
164     Vector<RefPtr<WorkItemWin> > m_workItemQueue;
165
166     Mutex m_handlesLock;
167     HashMap<HANDLE, RefPtr<HandleWorkItem> > m_handles;
168
169     HANDLE m_timerQueue;
170 #elif PLATFORM(QT)
171     class WorkItemQt;
172     QThread* m_workThread;
173     friend class WorkItemQt;
174 #elif PLATFORM(GTK)
175     static void startWorkQueueThread(WorkQueue*);
176     void workQueueThreadBody();
177     void dispatchOnSource(GSource*, const Function<void()>&, GSourceFunc);
178
179     ThreadIdentifier m_workQueueThread;
180     GRefPtr<GMainContext> m_eventContext;
181     Mutex m_eventLoopLock;
182     GRefPtr<GMainLoop> m_eventLoop;
183     Mutex m_eventSourcesLock;
184     class EventSource;
185     HashMap<int, Vector<EventSource*> > m_eventSources;
186     typedef HashMap<int, Vector<EventSource*> >::iterator EventSourceIterator; 
187 #elif PLATFORM(EFL)
188     fd_set m_fileDescriptorSet;
189     int m_maxFileDescriptor;
190     int m_readFromPipeDescriptor;
191     int m_writeToPipeDescriptor;
192     bool m_threadLoop;
193
194     Vector<Function<void()> > m_workItemQueue;
195     Mutex m_workItemQueueLock;
196
197     int m_socketDescriptor;
198     Function<void()> m_socketEventHandler;
199
200     HashMap<int, OwnPtr<Ecore_Timer> > m_timers;
201
202     void sendMessageToThread(const char*);
203     static void* workQueueThread(WorkQueue*);
204     void performWork();
205     void performFileDescriptorWork();
206     static bool timerFired(void*);
207 #endif
208 };
209
210 #endif // WorkQueue_h