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 RunLoop_h 29#define RunLoop_h 30 31#include <wtf/HashMap.h> 32#include <wtf/PassOwnPtr.h> 33#include <wtf/ThreadSpecific.h> 34#include <wtf/Threading.h> 35#include <wtf/Vector.h> 36#if PLATFORM(GTK) 37#include <wtf/gobject/GRefPtr.h> 38typedef struct _GSource GSource; 39typedef struct _GMainLoop GMainLoop; 40typedef struct _GMainContext GMainContext; 41typedef int gboolean; 42#endif 43 44class WorkItem; 45 46namespace CoreIPC { 47 class BinarySemaphore; 48} 49 50class RunLoop { 51public: 52 // Must be called from the main thread. 53 static void initializeMainRunLoop(); 54 55 static RunLoop* current(); 56 static RunLoop* main(); 57 58 void scheduleWork(PassOwnPtr<WorkItem>); 59 60#if PLATFORM(WIN) 61 // The absoluteTime is in seconds, starting on January 1, 1970. The time is assumed to use the 62 // same time zone as WTF::currentTime(). Dispatches sent (not posted) messages to the passed-in 63 // set of HWNDs until the semaphore is signaled or absoluteTime is reached. Returns true if the 64 // semaphore is signaled, false otherwise. 65 static bool dispatchSentMessagesUntil(const Vector<HWND>& windows, CoreIPC::BinarySemaphore&, double absoluteTime); 66#endif 67 68 static void run(); 69 void stop(); 70 71 class TimerBase { 72 friend class RunLoop; 73 public: 74 TimerBase(RunLoop*); 75 virtual ~TimerBase(); 76 77 void startRepeating(double repeatInterval) { start(repeatInterval, true); } 78 void startOneShot(double interval) { start(interval, false); } 79 80 void stop(); 81 bool isActive() const; 82 83 virtual void fired() = 0; 84 85 private: 86 void start(double nextFireInterval, bool repeat); 87 88 RunLoop* m_runLoop; 89 90#if PLATFORM(WIN) 91 static void timerFired(RunLoop*, uint64_t ID); 92 uint64_t m_ID; 93 bool m_isRepeating; 94#elif PLATFORM(MAC) 95 static void timerFired(CFRunLoopTimerRef, void*); 96 CFRunLoopTimerRef m_timer; 97#elif PLATFORM(QT) 98 static void timerFired(RunLoop*, int ID); 99 int m_ID; 100 bool m_isRepeating; 101#elif PLATFORM(GTK) 102 static gboolean timerFiredCallback(RunLoop::TimerBase*); 103 static void destroyNotifyCallback(RunLoop::TimerBase*); 104 gboolean isRepeating() const { return m_isRepeating; } 105 void clearTimerSource(); 106 GRefPtr<GSource> m_timerSource; 107 gboolean m_isRepeating; 108#endif 109 }; 110 111 template <typename TimerFiredClass> 112 class Timer : public TimerBase { 113 public: 114 typedef void (TimerFiredClass::*TimerFiredFunction)(); 115 116 Timer(RunLoop* runLoop, TimerFiredClass* o, TimerFiredFunction f) 117 : TimerBase(runLoop) 118 , m_object(o) 119 , m_function(f) 120 { 121 } 122 123 private: 124 virtual void fired() { (m_object->*m_function)(); } 125 126 TimerFiredClass* m_object; 127 TimerFiredFunction m_function; 128 }; 129 130private: 131 friend class WTF::ThreadSpecific<RunLoop>; 132 133 RunLoop(); 134 ~RunLoop(); 135 136 void performWork(); 137 void wakeUp(); 138 139 Mutex m_workItemQueueLock; 140 Vector<WorkItem*> m_workItemQueue; 141 142#if PLATFORM(WIN) 143 static bool registerRunLoopMessageWindowClass(); 144 static LRESULT CALLBACK RunLoopWndProc(HWND, UINT, WPARAM, LPARAM); 145 LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 146 HWND m_runLoopMessageWindow; 147 148 typedef HashMap<uint64_t, TimerBase*> TimerMap; 149 TimerMap m_activeTimers; 150#elif PLATFORM(MAC) 151 static void performWork(void*); 152 CFRunLoopRef m_runLoop; 153 CFRunLoopSourceRef m_runLoopSource; 154#elif PLATFORM(QT) 155 typedef HashMap<int, TimerBase*> TimerMap; 156 TimerMap m_activeTimers; 157 class TimerObject; 158 TimerObject* m_timerObject; 159#elif PLATFORM(GTK) 160public: 161 static gboolean queueWork(RunLoop*); 162 GMainLoop* mainLoop(); 163private: 164 GMainContext* m_runLoopContext; 165 GMainLoop* m_runLoopMain; 166#endif 167}; 168 169#endif // RunLoop_h 170