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/Deque.h> 32#include <wtf/Forward.h> 33#include <wtf/FunctionDispatcher.h> 34#include <wtf/Functional.h> 35#include <wtf/HashMap.h> 36#include <wtf/RetainPtr.h> 37#include <wtf/Threading.h> 38 39#if PLATFORM(GTK) 40#include <wtf/gobject/GRefPtr.h> 41#endif 42 43#if PLATFORM(EFL) 44#include <Ecore.h> 45#endif 46 47namespace WebCore { 48 49class RunLoop : public FunctionDispatcher { 50public: 51 // Must be called from the main thread (except for the Mac platform, where it 52 // can be called from any thread). 53 static void initializeMainRunLoop(); 54 55 // Must be called before entering main run loop. If called, application style run loop will be used, handling events. 56 static void setUseApplicationRunLoopOnMainRunLoop(); 57 58 static RunLoop* current(); 59 static RunLoop* main(); 60 ~RunLoop(); 61 62 virtual void dispatch(const Function<void()>&) OVERRIDE; 63 64 static void run(); 65 void stop(); 66 void wakeUp(); 67 68#if PLATFORM(MAC) 69 void runForDuration(double duration); 70#endif 71 72 class TimerBase { 73 friend class RunLoop; 74 public: 75 explicit TimerBase(RunLoop*); 76 virtual ~TimerBase(); 77 78 void startRepeating(double repeatInterval) { start(repeatInterval, true); } 79 void startOneShot(double interval) { start(interval, false); } 80 81 void stop(); 82 bool isActive() const; 83 84 virtual void fired() = 0; 85 86 private: 87 void start(double nextFireInterval, bool repeat); 88 89 RunLoop* m_runLoop; 90 91#if PLATFORM(WIN) 92 static void timerFired(RunLoop*, uint64_t ID); 93 uint64_t m_ID; 94 bool m_isRepeating; 95#elif PLATFORM(MAC) 96 static void timerFired(CFRunLoopTimerRef, void*); 97 RetainPtr<CFRunLoopTimerRef> m_timer; 98#elif PLATFORM(QT) 99 static void timerFired(RunLoop*, int ID); 100 int m_ID; 101 bool m_isRepeating; 102#elif PLATFORM(GTK) 103 static gboolean timerFiredCallback(RunLoop::TimerBase*); 104 gboolean isRepeating() const { return m_isRepeating; } 105 void clearTimerSource(); 106 GRefPtr<GSource> m_timerSource; 107 gboolean m_isRepeating; 108#elif PLATFORM(EFL) 109 static bool timerFired(void* data); 110 Ecore_Timer* m_timer; 111 bool m_isRepeating; 112#endif 113 }; 114 115 template <typename TimerFiredClass> 116 class Timer : public TimerBase { 117 public: 118 typedef void (TimerFiredClass::*TimerFiredFunction)(); 119 120 Timer(RunLoop* runLoop, TimerFiredClass* o, TimerFiredFunction f) 121 : TimerBase(runLoop) 122 , m_object(o) 123 , m_function(f) 124 { 125 } 126 127 private: 128 virtual void fired() { (m_object->*m_function)(); } 129 130 TimerFiredClass* m_object; 131 TimerFiredFunction m_function; 132 }; 133 134 class Holder; 135 136private: 137 RunLoop(); 138 139 void performWork(); 140 141 Mutex m_functionQueueLock; 142 Deque<Function<void()> > m_functionQueue; 143 144#if PLATFORM(WIN) 145 static bool registerRunLoopMessageWindowClass(); 146 static LRESULT CALLBACK RunLoopWndProc(HWND, UINT, WPARAM, LPARAM); 147 LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 148 HWND m_runLoopMessageWindow; 149 150 typedef HashMap<uint64_t, TimerBase*> TimerMap; 151 TimerMap m_activeTimers; 152#elif PLATFORM(MAC) 153 static void performWork(void*); 154 RetainPtr<CFRunLoopRef> m_runLoop; 155 RetainPtr<CFRunLoopSourceRef> m_runLoopSource; 156 int m_nestingLevel; 157#elif PLATFORM(QT) 158 typedef HashMap<int, TimerBase*> TimerMap; 159 TimerMap m_activeTimers; 160 class TimerObject; 161 TimerObject* m_timerObject; 162#elif PLATFORM(GTK) 163public: 164 static gboolean queueWork(RunLoop*); 165 GMainLoop* innermostLoop(); 166 void pushNestedMainLoop(GMainLoop*); 167 void popNestedMainLoop(); 168private: 169 GRefPtr<GMainContext> m_runLoopContext; 170 Vector<GRefPtr<GMainLoop> > m_runLoopMainLoops; 171#elif PLATFORM(EFL) 172 bool m_initEfl; 173 174 Mutex m_pipeLock; 175 OwnPtr<Ecore_Pipe> m_pipe; 176 177 Mutex m_wakeUpEventRequestedLock; 178 bool m_wakeUpEventRequested; 179 180 static void wakeUpEvent(void* data, void*, unsigned int); 181#endif 182}; 183 184} // namespace WebCore 185 186#endif // RunLoop_h 187