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>
37 #include <wtf/HashMap.h>
38 #include <wtf/PassOwnPtr.h>
39 #include <wtf/RefCounted.h>
40 #include <wtf/Threading.h>
41 #include <wtf/Vector.h>
44 #include <QSocketNotifier>
45 #include "PlatformProcessIdentifier.h"
49 #include "PlatformProcessIdentifier.h"
50 typedef struct _GMainContext GMainContext;
51 typedef struct _GMainLoop GMainLoop;
52 typedef gboolean (*GSourceFunc) (gpointer data);
56 WTF_MAKE_NONCOPYABLE(WorkQueue);
59 explicit WorkQueue(const char* name);
62 // Will schedule the given work item to run as soon as possible.
63 void scheduleWork(PassOwnPtr<WorkItem>);
65 // Will schedule the given work item to run after the given delay (in seconds).
66 void scheduleWorkAfterDelay(PassOwnPtr<WorkItem>, double delay);
71 enum MachPortEventType {
72 // Fired when there is data on the given receive right.
73 MachPortDataAvailable,
75 // Fired when the receive right for this send right has been destroyed.
76 MachPortDeadNameNotification
79 // Will execute the given work item whenever the given mach port event fires.
80 // Note that this will adopt the mach port and destroy it when the work queue is invalidated.
81 void registerMachPortEventHandler(mach_port_t, MachPortEventType, PassOwnPtr<WorkItem>);
82 void unregisterMachPortEventHandler(mach_port_t);
84 void registerHandle(HANDLE, PassOwnPtr<WorkItem>);
85 void unregisterAndCloseHandle(HANDLE);
87 QSocketNotifier* registerSocketEventHandler(int, QSocketNotifier::Type, PassOwnPtr<WorkItem>);
88 void scheduleWorkOnTermination(WebKit::PlatformProcessIdentifier, PassOwnPtr<WorkItem>);
90 void registerEventSourceHandler(int, int, PassOwnPtr<WorkItem>);
91 void unregisterEventSourceHandler(int);
92 void scheduleWorkOnTermination(WebKit::PlatformProcessIdentifier, PassOwnPtr<WorkItem>);
96 // FIXME: Use an atomic boolean here instead.
100 void platformInitialize(const char* name);
101 void platformInvalidate();
105 static void executeWorkItem(void*);
106 Mutex m_eventSourcesMutex;
108 HashMap<mach_port_t, EventSource*> m_eventSources;
109 dispatch_queue_t m_dispatchQueue;
112 class WorkItemWin : public ThreadSafeRefCounted<WorkItemWin> {
114 static PassRefPtr<WorkItemWin> create(PassOwnPtr<WorkItem>, WorkQueue*);
115 virtual ~WorkItemWin();
117 WorkItem* item() const { return m_item.get(); }
118 WorkQueue* queue() const { return m_queue; }
121 WorkItemWin(PassOwnPtr<WorkItem>, WorkQueue*);
124 OwnPtr<WorkItem> m_item;
128 class HandleWorkItem : public WorkItemWin {
130 static PassRefPtr<HandleWorkItem> createByAdoptingHandle(HANDLE, PassOwnPtr<WorkItem>, WorkQueue*);
131 virtual ~HandleWorkItem();
133 void setWaitHandle(HANDLE waitHandle) { m_waitHandle = waitHandle; }
134 HANDLE waitHandle() const { return m_waitHandle; }
137 HandleWorkItem(HANDLE, PassOwnPtr<WorkItem>, WorkQueue*);
143 static void CALLBACK handleCallback(void* context, BOOLEAN timerOrWaitFired);
144 static void CALLBACK timerCallback(void* context, BOOLEAN timerOrWaitFired);
145 static DWORD WINAPI workThreadCallback(void* context);
147 bool tryRegisterAsWorkThread();
148 void unregisterAsWorkThread();
149 void performWorkOnRegisteredWorkThread();
151 static void unregisterWaitAndDestroyItemSoon(PassRefPtr<HandleWorkItem>);
152 static DWORD WINAPI unregisterWaitAndDestroyItemCallback(void* context);
154 volatile LONG m_isWorkThreadRegistered;
156 Mutex m_workItemQueueLock;
157 Vector<RefPtr<WorkItemWin> > m_workItemQueue;
160 HashMap<HANDLE, RefPtr<HandleWorkItem> > m_handles;
165 HashMap<QObject*, WorkItemQt*> m_signalListeners;
166 QThread* m_workThread;
167 friend class WorkItemQt;
169 static void* startWorkQueueThread(WorkQueue*);
170 void workQueueThreadBody();
171 void scheduleWorkOnSource(GSource*, PassOwnPtr<WorkItem>, GSourceFunc);
173 ThreadIdentifier m_workQueueThread;
174 GMainContext* m_eventContext;
175 Mutex m_eventLoopLock;
176 GMainLoop* m_eventLoop;
177 Mutex m_eventSourcesLock;
179 HashMap<int, Vector<EventSource*> > m_eventSources;
180 typedef HashMap<int, Vector<EventSource*> >::iterator EventSourceIterator;
184 #endif // WorkQueue_h