[GTK] Clean up RunLoop implementation
[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/gobject/GMainLoopSource.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         GMainLoopSource m_timerSource;
104 #endif
105     };
106
107     template <typename TimerFiredClass>
108     class Timer : public TimerBase {
109     public:
110         typedef void (TimerFiredClass::*TimerFiredFunction)();
111
112         Timer(RunLoop& runLoop, TimerFiredClass* o, TimerFiredFunction f)
113             : TimerBase(runLoop)
114             , m_object(o)
115             , m_function(f)
116         {
117         }
118
119     private:
120         virtual void fired() { (m_object->*m_function)(); }
121
122         TimerFiredClass* m_object;
123         TimerFiredFunction m_function;
124     };
125
126     class Holder;
127
128 private:
129     RunLoop();
130
131     void performWork();
132
133     Mutex m_functionQueueLock;
134     Deque<std::function<void ()>> m_functionQueue;
135
136 #if PLATFORM(WIN)
137     static bool registerRunLoopMessageWindowClass();
138     static LRESULT CALLBACK RunLoopWndProc(HWND, UINT, WPARAM, LPARAM);
139     LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
140     HWND m_runLoopMessageWindow;
141
142     typedef HashMap<uint64_t, TimerBase*> TimerMap;
143     TimerMap m_activeTimers;
144 #elif PLATFORM(COCOA)
145     static void performWork(void*);
146     RetainPtr<CFRunLoopRef> m_runLoop;
147     RetainPtr<CFRunLoopSourceRef> m_runLoopSource;
148     int m_nestingLevel;
149 #elif PLATFORM(EFL)
150     Mutex m_pipeLock;
151     EflUniquePtr<Ecore_Pipe> m_pipe;
152
153     Mutex m_wakeUpEventRequestedLock;
154     bool m_wakeUpEventRequested;
155
156     static void wakeUpEvent(void* data, void*, unsigned);
157 #elif USE(GLIB)
158 public:
159     static gboolean queueWork(RunLoop*);
160 private:
161     GRefPtr<GMainContext> m_mainContext;
162     Vector<GRefPtr<GMainLoop>> m_mainLoops;
163 #endif
164 };
165
166 } // namespace WTF
167
168 using WTF::RunLoop;
169
170 #endif // RunLoop_h