Added missing override and final specifiers
[WebKit-https.git] / Source / WTF / wtf / RunLoop.h
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/Condition.h>
32 #include <wtf/Deque.h>
33 #include <wtf/Forward.h>
34 #include <wtf/FunctionDispatcher.h>
35 #include <wtf/HashMap.h>
36 #include <wtf/RetainPtr.h>
37 #include <wtf/Threading.h>
38
39 #if USE(GLIB_EVENT_LOOP)
40 #include <wtf/glib/GRefPtr.h>
41 #endif
42
43 #if USE(EFL_EVENT_LOOP)
44 #include <Ecore.h>
45 #include <wtf/efl/UniquePtrEfl.h>
46 #endif
47
48 namespace WTF {
49
50 class RunLoop : public FunctionDispatcher {
51     WTF_MAKE_NONCOPYABLE(RunLoop);
52 public:
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     void dispatch(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 USE(COCOA_EVENT_LOOP)
69     WTF_EXPORT_PRIVATE void runForDuration(double duration);
70 #endif
71
72 #if USE(GLIB_EVENT_LOOP)
73     WTF_EXPORT_PRIVATE GMainContext* mainContext() const { return m_mainContext.get(); }
74 #endif
75
76 #if USE(GENERIC_EVENT_LOOP)
77     // Run the single iteration of the RunLoop. It consumes the pending tasks and expired timers, but it won't be blocked.
78     WTF_EXPORT_PRIVATE static void iterate();
79 #endif
80
81 #if USE(GLIB_EVENT_LOOP) || USE(GENERIC_EVENT_LOOP)
82     WTF_EXPORT_PRIVATE void dispatchAfter(std::chrono::nanoseconds, Function<void ()>&&);
83 #endif
84
85     class TimerBase {
86         friend class RunLoop;
87     public:
88         WTF_EXPORT_PRIVATE explicit TimerBase(RunLoop&);
89         WTF_EXPORT_PRIVATE virtual ~TimerBase();
90
91         void startRepeating(double repeatInterval) { start(repeatInterval, true); }
92         void startRepeating(std::chrono::milliseconds repeatInterval) { startRepeating(repeatInterval.count() * 0.001); }
93         void startOneShot(double interval) { start(interval, false); }
94         void startOneShot(std::chrono::milliseconds interval) { start(interval.count() * 0.001, false); }
95
96         WTF_EXPORT_PRIVATE void stop();
97         WTF_EXPORT_PRIVATE bool isActive() const;
98
99         virtual void fired() = 0;
100
101 #if USE(GLIB_EVENT_LOOP)
102         void setPriority(int);
103 #endif
104
105     private:
106         WTF_EXPORT_PRIVATE void start(double nextFireInterval, bool repeat);
107
108         RunLoop& m_runLoop;
109
110 #if USE(WINDOWS_EVENT_LOOP)
111         static void timerFired(RunLoop*, uint64_t ID);
112         uint64_t m_ID;
113         bool m_isRepeating;
114 #elif USE(COCOA_EVENT_LOOP)
115         static void timerFired(CFRunLoopTimerRef, void*);
116         RetainPtr<CFRunLoopTimerRef> m_timer;
117 #elif USE(EFL_EVENT_LOOP)
118         static bool timerFired(void* data);
119         Ecore_Timer* m_timer;
120         bool m_isRepeating;
121 #elif USE(GLIB_EVENT_LOOP)
122         void updateReadyTime();
123         GRefPtr<GSource> m_source;
124         bool m_isRepeating { false };
125         std::chrono::microseconds m_fireInterval { 0 };
126 #elif USE(GENERIC_EVENT_LOOP)
127         class ScheduledTask;
128         RefPtr<ScheduledTask> m_scheduledTask;
129 #endif
130     };
131
132     template <typename TimerFiredClass>
133     class Timer : public TimerBase {
134     public:
135         typedef void (TimerFiredClass::*TimerFiredFunction)();
136
137         Timer(RunLoop& runLoop, TimerFiredClass* o, TimerFiredFunction f)
138             : TimerBase(runLoop)
139             , m_object(o)
140             , m_function(f)
141         {
142         }
143
144     private:
145         void fired() override { (m_object->*m_function)(); }
146
147         TimerFiredClass* m_object;
148         TimerFiredFunction m_function;
149     };
150
151     class Holder;
152
153 private:
154     RunLoop();
155
156     void performWork();
157
158     Mutex m_functionQueueLock;
159     Deque<Function<void ()>> m_functionQueue;
160
161 #if USE(WINDOWS_EVENT_LOOP)
162     static bool registerRunLoopMessageWindowClass();
163     static LRESULT CALLBACK RunLoopWndProc(HWND, UINT, WPARAM, LPARAM);
164     LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
165     HWND m_runLoopMessageWindow;
166
167     typedef HashMap<uint64_t, TimerBase*> TimerMap;
168     TimerMap m_activeTimers;
169 #elif USE(COCOA_EVENT_LOOP)
170     static void performWork(void*);
171     RetainPtr<CFRunLoopRef> m_runLoop;
172     RetainPtr<CFRunLoopSourceRef> m_runLoopSource;
173     int m_nestingLevel;
174 #elif USE(EFL_EVENT_LOOP)
175     Mutex m_pipeLock;
176     EflUniquePtr<Ecore_Pipe> m_pipe;
177
178     Mutex m_wakeUpEventRequestedLock;
179     bool m_wakeUpEventRequested;
180
181     static void wakeUpEvent(void* data, void*, unsigned);
182 #elif USE(GLIB_EVENT_LOOP)
183     GRefPtr<GMainContext> m_mainContext;
184     Vector<GRefPtr<GMainLoop>> m_mainLoops;
185     GRefPtr<GSource> m_source;
186 #elif USE(GENERIC_EVENT_LOOP)
187     void schedule(RefPtr<TimerBase::ScheduledTask>&&);
188     void schedule(const LockHolder&, RefPtr<TimerBase::ScheduledTask>&&);
189     void wakeUp(const LockHolder&);
190     void scheduleAndWakeUp(RefPtr<TimerBase::ScheduledTask>);
191
192     enum class RunMode {
193         Iterate,
194         Drain
195     };
196
197     enum class Status {
198         Clear,
199         Stopping,
200     };
201     void runImpl(RunMode);
202     bool populateTasks(RunMode, Status&, Deque<RefPtr<TimerBase::ScheduledTask>>&);
203
204     Lock m_loopLock;
205     Condition m_readyToRun;
206     Condition m_stopCondition;
207     Vector<RefPtr<TimerBase::ScheduledTask>> m_schedules;
208     Vector<Status*> m_mainLoops;
209     bool m_shutdown { false };
210     bool m_pendingTasks { false };
211 #endif
212 };
213
214 } // namespace WTF
215
216 using WTF::RunLoop;
217
218 #endif // RunLoop_h