#ifndef RunLoop_h
#define RunLoop_h
#include <wtf/Deque.h>
#include <wtf/Forward.h>
#include <wtf/Functional.h>
#include <wtf/HashMap.h>
#include <wtf/ThreadSpecific.h>
#include <wtf/Threading.h>
#if PLATFORM(GTK)
#include <wtf/gobject/GRefPtr.h>
#endif
#if PLATFORM(EFL)
#include <Ecore.h>
#endif
namespace WebCore {
class RunLoop {
public:
static void initializeMainRunLoop();
static RunLoop* current();
static RunLoop* main();
void dispatch(const Function<void()>&);
static void run();
void stop();
void wakeUp();
#if PLATFORM(MAC)
void runForDuration(double duration);
#endif
class TimerBase {
friend class RunLoop;
public:
TimerBase(RunLoop*);
virtual ~TimerBase();
void startRepeating(double repeatInterval) { start(repeatInterval, true); }
void startOneShot(double interval) { start(interval, false); }
void stop();
bool isActive() const;
virtual void fired() = 0;
private:
void start(double nextFireInterval, bool repeat);
RunLoop* m_runLoop;
#if PLATFORM(WIN)
static void timerFired(RunLoop*, uint64_t ID);
uint64_t m_ID;
bool m_isRepeating;
#elif PLATFORM(MAC)
static void timerFired(CFRunLoopTimerRef, void*);
CFRunLoopTimerRef m_timer;
#elif PLATFORM(QT)
static void timerFired(RunLoop*, int ID);
int m_ID;
bool m_isRepeating;
#elif PLATFORM(GTK)
static gboolean timerFiredCallback(RunLoop::TimerBase*);
gboolean isRepeating() const { return m_isRepeating; }
void clearTimerSource();
GRefPtr<GSource> m_timerSource;
gboolean m_isRepeating;
#elif PLATFORM(EFL)
static bool timerFired(void* data);
OwnPtr<Ecore_Timer> m_timer;
bool m_isRepeating;
#endif
};
template <typename TimerFiredClass>
class Timer : public TimerBase {
public:
typedef void (TimerFiredClass::*TimerFiredFunction)();
Timer(RunLoop* runLoop, TimerFiredClass* o, TimerFiredFunction f)
: TimerBase(runLoop)
, m_object(o)
, m_function(f)
{
}
private:
virtual void fired() { (m_object->*m_function)(); }
TimerFiredClass* m_object;
TimerFiredFunction m_function;
};
private:
friend class WTF::ThreadSpecific<RunLoop>;
RunLoop();
~RunLoop();
void performWork();
Mutex m_functionQueueLock;
Deque<Function<void()> > m_functionQueue;
#if PLATFORM(WIN)
static bool registerRunLoopMessageWindowClass();
static LRESULT CALLBACK RunLoopWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
HWND m_runLoopMessageWindow;
typedef HashMap<uint64_t, TimerBase*> TimerMap;
TimerMap m_activeTimers;
#elif PLATFORM(MAC)
RunLoop(CFRunLoopRef);
static void performWork(void*);
CFRunLoopRef m_runLoop;
CFRunLoopSourceRef m_runLoopSource;
int m_nestingLevel;
#elif PLATFORM(QT)
typedef HashMap<int, TimerBase*> TimerMap;
TimerMap m_activeTimers;
class TimerObject;
TimerObject* m_timerObject;
#elif PLATFORM(GTK)
public:
static gboolean queueWork(RunLoop*);
GMainLoop* innermostLoop();
void pushNestedMainLoop(GMainLoop*);
void popNestedMainLoop();
private:
GRefPtr<GMainContext> m_runLoopContext;
Vector<GRefPtr<GMainLoop> > m_runLoopMainLoops;
#elif PLATFORM(EFL)
bool m_initEfl;
OwnPtr<Ecore_Pipe> m_pipe;
static void wakeUpEvent(void* data, void*, unsigned int);
#endif
};
}
#endif // RunLoop_h