2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
32 #include <dispatch/dispatch.h>
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>
44 #if (PLATFORM(QT) && !OS(DARWIN)) || PLATFORM(GTK) || PLATFORM(EFL)
45 #include "PlatformProcessIdentifier.h"
48 #if PLATFORM(QT) && !OS(DARWIN)
49 #include <QSocketNotifier>
53 #include <wtf/gobject/GRefPtr.h>
54 typedef gboolean (*GSourceFunc) (gpointer data);
60 WTF_MAKE_NONCOPYABLE(WorkQueue);
63 explicit WorkQueue(const char* name);
66 // Will dispatch the given function to run as soon as possible.
67 void dispatch(const Function<void()>&);
69 // Will dispatch the given function after the given delay (in seconds).
70 void dispatchAfterDelay(const Function<void()>&, double delay);
75 enum MachPortEventType {
76 // Fired when there is data on the given receive right.
77 MachPortDataAvailable,
79 // Fired when the receive right for this send right has been destroyed.
80 MachPortDeadNameNotification
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);
88 void registerHandle(HANDLE, const Function<void()>&);
89 void unregisterAndCloseHandle(HANDLE);
91 QSocketNotifier* registerSocketEventHandler(int, QSocketNotifier::Type, const Function<void()>&);
92 void dispatchOnTermination(WebKit::PlatformProcessIdentifier, const Function<void()>&);
94 void registerEventSourceHandler(int, int, const Function<void()>&);
95 void unregisterEventSourceHandler(int);
96 void dispatchOnTermination(WebKit::PlatformProcessIdentifier, const Function<void()>&);
98 void registerSocketEventHandler(int, const Function<void()>&);
99 void unregisterSocketEventHandler(int);
103 // FIXME: Use an atomic boolean here instead.
104 Mutex m_isValidMutex;
107 void platformInitialize(const char* name);
108 void platformInvalidate();
112 static void executeFunction(void*);
113 Mutex m_eventSourcesMutex;
115 HashMap<mach_port_t, EventSource*> m_eventSources;
116 dispatch_queue_t m_dispatchQueue;
119 class WorkItemWin : public ThreadSafeRefCounted<WorkItemWin> {
121 static PassRefPtr<WorkItemWin> create(const Function<void()>&, WorkQueue*);
122 virtual ~WorkItemWin();
124 Function<void()>& function() { return m_function; }
125 WorkQueue* queue() const { return m_queue; }
128 WorkItemWin(const Function<void()>&, WorkQueue*);
131 Function<void()> m_function;
135 class HandleWorkItem : public WorkItemWin {
137 static PassRefPtr<HandleWorkItem> createByAdoptingHandle(HANDLE, const Function<void()>&, WorkQueue*);
138 virtual ~HandleWorkItem();
140 void setWaitHandle(HANDLE waitHandle) { m_waitHandle = waitHandle; }
141 HANDLE waitHandle() const { return m_waitHandle; }
144 HandleWorkItem(HANDLE, const Function<void()>&, WorkQueue*);
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);
154 bool tryRegisterAsWorkThread();
155 void unregisterAsWorkThread();
156 void performWorkOnRegisteredWorkThread();
158 static void unregisterWaitAndDestroyItemSoon(PassRefPtr<HandleWorkItem>);
159 static DWORD WINAPI unregisterWaitAndDestroyItemCallback(void* context);
161 volatile LONG m_isWorkThreadRegistered;
163 Mutex m_workItemQueueLock;
164 Vector<RefPtr<WorkItemWin> > m_workItemQueue;
167 HashMap<HANDLE, RefPtr<HandleWorkItem> > m_handles;
172 QThread* m_workThread;
173 friend class WorkItemQt;
175 static void startWorkQueueThread(WorkQueue*);
176 void workQueueThreadBody();
177 void dispatchOnSource(GSource*, const Function<void()>&, GSourceFunc);
179 ThreadIdentifier m_workQueueThread;
180 GRefPtr<GMainContext> m_eventContext;
181 Mutex m_eventLoopLock;
182 GRefPtr<GMainLoop> m_eventLoop;
183 Mutex m_eventSourcesLock;
185 HashMap<int, Vector<EventSource*> > m_eventSources;
186 typedef HashMap<int, Vector<EventSource*> >::iterator EventSourceIterator;
189 class TimerWorkItem {
191 static PassOwnPtr<TimerWorkItem> create(Function<void()>, double delay);
193 bool expired(fd_set* readFileDescriptorSet);
194 Function<void()> function() const { return m_function; }
195 int timerFileDescriptor() const { return m_timerFileDescriptor; }
198 TimerWorkItem(Function<void()>, int timerFileDescriptor);
201 Function<void()> m_function;
202 int m_timerFileDescriptor;
206 fd_set m_fileDescriptorSet;
207 int m_maxFileDescriptor;
208 int m_readFromPipeDescriptor;
209 int m_writeToPipeDescriptor;
212 Vector<Function<void()> > m_workItemQueue;
213 Mutex m_workItemQueueLock;
215 int m_socketDescriptor;
216 Function<void()> m_socketEventHandler;
219 Vector<OwnPtr<TimerWorkItem> > m_timerWorkItems;
220 Mutex m_timerWorkItemsLock;
222 HashMap<int, OwnPtr<Ecore_Timer> > m_timers;
225 void sendMessageToThread(const char*);
226 static void* workQueueThread(WorkQueue*);
228 void performFileDescriptorWork();
230 void performTimerFileDescriptorWork(fd_set* readFileDescriptorSet);
232 static bool timerFired(void*);
237 #endif // WorkQueue_h