summaryrefslogtreecommitdiffstats
path: root/Source/WebKit2/Platform/WorkQueue.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/Platform/WorkQueue.h')
-rw-r--r--Source/WebKit2/Platform/WorkQueue.h176
1 files changed, 176 insertions, 0 deletions
diff --git a/Source/WebKit2/Platform/WorkQueue.h b/Source/WebKit2/Platform/WorkQueue.h
new file mode 100644
index 0000000..78fa8b7
--- /dev/null
+++ b/Source/WebKit2/Platform/WorkQueue.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkQueue_h
+#define WorkQueue_h
+
+#if PLATFORM(MAC)
+#if HAVE(DISPATCH_H)
+#include <dispatch/dispatch.h>
+#endif
+#endif
+
+#include "WorkItem.h"
+#include <wtf/HashMap.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Threading.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(QT)
+class QLocalSocket;
+class QObject;
+class QThread;
+#elif PLATFORM(GTK)
+typedef struct _GMainContext GMainContext;
+typedef struct _GMainLoop GMainLoop;
+#endif
+
+class WorkQueue {
+public:
+ explicit WorkQueue(const char* name);
+ ~WorkQueue();
+
+ // Will schedule the given work item to run as soon as possible.
+ void scheduleWork(PassOwnPtr<WorkItem>);
+
+ // Will schedule the given work item to run after the given delay (in seconds).
+ void scheduleWorkAfterDelay(PassOwnPtr<WorkItem>, double delay);
+
+ void invalidate();
+
+#if PLATFORM(MAC)
+ enum MachPortEventType {
+ // Fired when there is data on the given receive right.
+ MachPortDataAvailable,
+
+ // Fired when the receive right for this send right has been destroyed.
+ MachPortDeadNameNotification
+ };
+
+ // Will execute the given work item whenever the given mach port event fires.
+ // Note that this will adopt the mach port and destroy it when the work queue is invalidated.
+ void registerMachPortEventHandler(mach_port_t, MachPortEventType, PassOwnPtr<WorkItem>);
+ void unregisterMachPortEventHandler(mach_port_t);
+#elif PLATFORM(WIN)
+ void registerHandle(HANDLE, PassOwnPtr<WorkItem>);
+ void unregisterAndCloseHandle(HANDLE);
+#elif PLATFORM(QT)
+ void connectSignal(QObject*, const char* signal, PassOwnPtr<WorkItem>);
+ void disconnectSignal(QObject*, const char* signal);
+
+ void moveSocketToWorkThread(QLocalSocket*);
+#elif PLATFORM(GTK)
+ void registerEventSourceHandler(int, int, PassOwnPtr<WorkItem>);
+ void unregisterEventSourceHandler(int);
+#endif
+
+private:
+ // FIXME: Use an atomic boolean here instead.
+ Mutex m_isValidMutex;
+ bool m_isValid;
+
+ void platformInitialize(const char* name);
+ void platformInvalidate();
+
+#if PLATFORM(MAC)
+#if HAVE(DISPATCH_H)
+ static void executeWorkItem(void*);
+ Mutex m_eventSourcesMutex;
+ class EventSource;
+ HashMap<mach_port_t, EventSource*> m_eventSources;
+ dispatch_queue_t m_dispatchQueue;
+#endif
+#elif PLATFORM(WIN)
+ class WorkItemWin : public ThreadSafeShared<WorkItemWin> {
+ public:
+ static PassRefPtr<WorkItemWin> create(PassOwnPtr<WorkItem>, WorkQueue*);
+ virtual ~WorkItemWin();
+
+ WorkItem* item() const { return m_item.get(); }
+ WorkQueue* queue() const { return m_queue; }
+
+ protected:
+ WorkItemWin(PassOwnPtr<WorkItem>, WorkQueue*);
+
+ private:
+ OwnPtr<WorkItem> m_item;
+ WorkQueue* m_queue;
+ };
+
+ class HandleWorkItem : public WorkItemWin {
+ public:
+ static PassRefPtr<HandleWorkItem> createByAdoptingHandle(HANDLE, PassOwnPtr<WorkItem>, WorkQueue*);
+ virtual ~HandleWorkItem();
+
+ void setWaitHandle(HANDLE waitHandle) { m_waitHandle = waitHandle; }
+ HANDLE waitHandle() const { return m_waitHandle; }
+
+ private:
+ HandleWorkItem(HANDLE, PassOwnPtr<WorkItem>, WorkQueue*);
+
+ HANDLE m_handle;
+ HANDLE m_waitHandle;
+ };
+
+ static void CALLBACK handleCallback(void* context, BOOLEAN timerOrWaitFired);
+ static DWORD WINAPI workThreadCallback(void* context);
+
+ bool tryRegisterAsWorkThread();
+ void unregisterAsWorkThread();
+ void performWorkOnRegisteredWorkThread();
+
+ static void unregisterWaitAndDestroyItemSoon(PassRefPtr<HandleWorkItem>);
+ static DWORD WINAPI unregisterWaitAndDestroyItemCallback(void* context);
+
+ volatile LONG m_isWorkThreadRegistered;
+
+ Mutex m_workItemQueueLock;
+ Vector<RefPtr<WorkItemWin> > m_workItemQueue;
+
+ Mutex m_handlesLock;
+ HashMap<HANDLE, RefPtr<HandleWorkItem> > m_handles;
+#elif PLATFORM(QT)
+ class WorkItemQt;
+ HashMap<QObject*, WorkItemQt*> m_signalListeners;
+ QThread* m_workThread;
+ friend class WorkItemQt;
+#elif PLATFORM(GTK)
+ static void* startWorkQueueThread(WorkQueue*);
+ void workQueueThreadBody();
+
+ ThreadIdentifier m_workQueueThread;
+ GMainContext* m_eventContext;
+ Mutex m_eventLoopLock;
+ GMainLoop* m_eventLoop;
+ Mutex m_eventSourcesLock;
+ class EventSource;
+ HashMap<int, Vector<EventSource*> > m_eventSources;
+ typedef HashMap<int, Vector<EventSource*> >::iterator EventSourceIterator;
+#endif
+};
+
+#endif // WorkQueue_h