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