diff options
Diffstat (limited to 'Source/WTF/wtf/RunLoop.h')
-rw-r--r-- | Source/WTF/wtf/RunLoop.h | 123 |
1 files changed, 73 insertions, 50 deletions
diff --git a/Source/WTF/wtf/RunLoop.h b/Source/WTF/wtf/RunLoop.h index dc13a9092..e92452795 100644 --- a/Source/WTF/wtf/RunLoop.h +++ b/Source/WTF/wtf/RunLoop.h @@ -28,81 +28,95 @@ #ifndef RunLoop_h #define RunLoop_h +#include <wtf/Condition.h> #include <wtf/Deque.h> #include <wtf/Forward.h> #include <wtf/FunctionDispatcher.h> -#include <wtf/Functional.h> #include <wtf/HashMap.h> #include <wtf/RetainPtr.h> #include <wtf/Threading.h> -#if USE(GLIB) -#include <wtf/gobject/GRefPtr.h> -#endif - -#if PLATFORM(EFL) -#include <Ecore.h> +#if USE(GLIB_EVENT_LOOP) +#include <wtf/glib/GRefPtr.h> #endif namespace WTF { class RunLoop : public FunctionDispatcher { + WTF_MAKE_NONCOPYABLE(RunLoop); public: // Must be called from the main thread (except for the Mac platform, where it // can be called from any thread). WTF_EXPORT_PRIVATE static void initializeMainRunLoop(); - WTF_EXPORT_PRIVATE static RunLoop* current(); - WTF_EXPORT_PRIVATE static RunLoop* main(); + WTF_EXPORT_PRIVATE static RunLoop& current(); + WTF_EXPORT_PRIVATE static RunLoop& main(); WTF_EXPORT_PRIVATE static bool isMain(); ~RunLoop(); - virtual void dispatch(std::function<void()>) override; + void dispatch(Function<void ()>&&) override; WTF_EXPORT_PRIVATE static void run(); WTF_EXPORT_PRIVATE void stop(); WTF_EXPORT_PRIVATE void wakeUp(); -#if PLATFORM(MAC) +#if USE(COCOA_EVENT_LOOP) WTF_EXPORT_PRIVATE void runForDuration(double duration); #endif - + +#if USE(GLIB_EVENT_LOOP) + WTF_EXPORT_PRIVATE GMainContext* mainContext() const { return m_mainContext.get(); } +#endif + +#if USE(GENERIC_EVENT_LOOP) + // Run the single iteration of the RunLoop. It consumes the pending tasks and expired timers, but it won't be blocked. + WTF_EXPORT_PRIVATE static void iterate(); +#endif + +#if USE(GLIB_EVENT_LOOP) || USE(GENERIC_EVENT_LOOP) + WTF_EXPORT_PRIVATE void dispatchAfter(std::chrono::nanoseconds, Function<void ()>&&); +#endif + class TimerBase { friend class RunLoop; public: - WTF_EXPORT_PRIVATE explicit TimerBase(RunLoop*); + WTF_EXPORT_PRIVATE explicit TimerBase(RunLoop&); WTF_EXPORT_PRIVATE virtual ~TimerBase(); void startRepeating(double repeatInterval) { start(repeatInterval, true); } + void startRepeating(std::chrono::milliseconds repeatInterval) { startRepeating(repeatInterval.count() * 0.001); } void startOneShot(double interval) { start(interval, false); } + void startOneShot(std::chrono::milliseconds interval) { start(interval.count() * 0.001, false); } WTF_EXPORT_PRIVATE void stop(); WTF_EXPORT_PRIVATE bool isActive() const; virtual void fired() = 0; +#if USE(GLIB_EVENT_LOOP) + void setPriority(int); +#endif + private: WTF_EXPORT_PRIVATE void start(double nextFireInterval, bool repeat); - RunLoop* m_runLoop; + RunLoop& m_runLoop; -#if PLATFORM(WIN) +#if USE(WINDOWS_EVENT_LOOP) static void timerFired(RunLoop*, uint64_t ID); uint64_t m_ID; bool m_isRepeating; -#elif PLATFORM(MAC) +#elif USE(COCOA_EVENT_LOOP) static void timerFired(CFRunLoopTimerRef, void*); RetainPtr<CFRunLoopTimerRef> m_timer; -#elif PLATFORM(EFL) - static bool timerFired(void* data); - Ecore_Timer* m_timer; - bool m_isRepeating; -#elif USE(GLIB) - static gboolean timerFiredCallback(RunLoop::TimerBase*); - gboolean isRepeating() const { return m_isRepeating; } - void clearTimerSource(); - GRefPtr<GSource> m_timerSource; - gboolean m_isRepeating; +#elif USE(GLIB_EVENT_LOOP) + void updateReadyTime(); + GRefPtr<GSource> m_source; + bool m_isRepeating { false }; + std::chrono::microseconds m_fireInterval { 0 }; +#elif USE(GENERIC_EVENT_LOOP) + class ScheduledTask; + RefPtr<ScheduledTask> m_scheduledTask; #endif }; @@ -111,7 +125,7 @@ public: public: typedef void (TimerFiredClass::*TimerFiredFunction)(); - Timer(RunLoop* runLoop, TimerFiredClass* o, TimerFiredFunction f) + Timer(RunLoop& runLoop, TimerFiredClass* o, TimerFiredFunction f) : TimerBase(runLoop) , m_object(o) , m_function(f) @@ -119,7 +133,7 @@ public: } private: - virtual void fired() { (m_object->*m_function)(); } + void fired() override { (m_object->*m_function)(); } TimerFiredClass* m_object; TimerFiredFunction m_function; @@ -133,9 +147,9 @@ private: void performWork(); Mutex m_functionQueueLock; - Deque<std::function<void ()>> m_functionQueue; + Deque<Function<void ()>> m_functionQueue; -#if PLATFORM(WIN) +#if USE(WINDOWS_EVENT_LOOP) static bool registerRunLoopMessageWindowClass(); static LRESULT CALLBACK RunLoopWndProc(HWND, UINT, WPARAM, LPARAM); LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); @@ -143,30 +157,39 @@ private: typedef HashMap<uint64_t, TimerBase*> TimerMap; TimerMap m_activeTimers; -#elif PLATFORM(MAC) +#elif USE(COCOA_EVENT_LOOP) static void performWork(void*); RetainPtr<CFRunLoopRef> m_runLoop; RetainPtr<CFRunLoopSourceRef> m_runLoopSource; - int m_nestingLevel; -#elif PLATFORM(EFL) - bool m_initEfl; - - Mutex m_pipeLock; - OwnPtr<Ecore_Pipe> m_pipe; - - Mutex m_wakeUpEventRequestedLock; - bool m_wakeUpEventRequested; +#elif USE(GLIB_EVENT_LOOP) + GRefPtr<GMainContext> m_mainContext; + Vector<GRefPtr<GMainLoop>> m_mainLoops; + GRefPtr<GSource> m_source; +#elif USE(GENERIC_EVENT_LOOP) + void schedule(RefPtr<TimerBase::ScheduledTask>&&); + void schedule(const LockHolder&, RefPtr<TimerBase::ScheduledTask>&&); + void wakeUp(const LockHolder&); + void scheduleAndWakeUp(RefPtr<TimerBase::ScheduledTask>); + + enum class RunMode { + Iterate, + Drain + }; - static void wakeUpEvent(void* data, void*, unsigned); -#elif USE(GLIB) -public: - static gboolean queueWork(RunLoop*); - GMainLoop* innermostLoop(); - void pushNestedMainLoop(GMainLoop*); - void popNestedMainLoop(); -private: - GRefPtr<GMainContext> m_runLoopContext; - Vector<GRefPtr<GMainLoop>> m_runLoopMainLoops; + enum class Status { + Clear, + Stopping, + }; + void runImpl(RunMode); + bool populateTasks(RunMode, Status&, Deque<RefPtr<TimerBase::ScheduledTask>>&); + + Lock m_loopLock; + Condition m_readyToRun; + Condition m_stopCondition; + Vector<RefPtr<TimerBase::ScheduledTask>> m_schedules; + Vector<Status*> m_mainLoops; + bool m_shutdown { false }; + bool m_pendingTasks { false }; #endif }; |