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> 38 typedef struct _GSource GSource; 39 typedef struct _GMainLoop GMainLoop; 40 typedef struct _GMainContext GMainContext; 41 typedef int gboolean; 42 #endif 43 44 class WorkItem; 45 46 namespace CoreIPC { 47 class BinarySemaphore; 48 } 49 50 class RunLoop { 51 public: 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 startRepeating(double repeatInterval)77 void startRepeating(double repeatInterval) { start(repeatInterval, true); } startOneShot(double interval)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*); isRepeating()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 Timer(RunLoop * runLoop,TimerFiredClass * o,TimerFiredFunction f)116 Timer(RunLoop* runLoop, TimerFiredClass* o, TimerFiredFunction f) 117 : TimerBase(runLoop) 118 , m_object(o) 119 , m_function(f) 120 { 121 } 122 123 private: fired()124 virtual void fired() { (m_object->*m_function)(); } 125 126 TimerFiredClass* m_object; 127 TimerFiredFunction m_function; 128 }; 129 130 private: 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) 160 public: 161 static gboolean queueWork(RunLoop*); 162 GMainLoop* mainLoop(); 163 private: 164 GMainContext* m_runLoopContext; 165 GMainLoop* m_runLoopMain; 166 #endif 167 }; 168 169 #endif // RunLoop_h 170