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