summaryrefslogtreecommitdiff
path: root/Source/WTF/wtf/RunLoop.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WTF/wtf/RunLoop.h')
-rw-r--r--Source/WTF/wtf/RunLoop.h123
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
};