GenericTaskQueue.cpp [plain text]
#include "config.h"
#include "GenericTaskQueue.h"
#include <wtf/Lock.h>
#include <wtf/MainThread.h>
#include <wtf/NeverDestroyed.h>
namespace WebCore {
TaskDispatcher<Timer>::TaskDispatcher()
{
}
void TaskDispatcher<Timer>::postTask(Function<void()>&& function)
{
{
auto locker = holdLock(sharedLock());
m_pendingTasks.append(WTFMove(function));
pendingDispatchers().append(makeWeakPtr(*this));
}
auto startTimer = [] {
if (!sharedTimer().isActive())
sharedTimer().startOneShot(0_s);
};
if (isMainThread())
startTimer();
else
callOnMainThread(WTFMove(startTimer));
}
Timer& TaskDispatcher<Timer>::sharedTimer()
{
ASSERT(isMainThread());
static NeverDestroyed<Timer> timer([] { TaskDispatcher<Timer>::sharedTimerFired(); });
return timer.get();
}
Lock& TaskDispatcher<Timer>::sharedLock()
{
static Lock lock;
return lock;
}
void TaskDispatcher<Timer>::sharedTimerFired()
{
ASSERT(!sharedTimer().isActive());
Deque<WeakPtr<TaskDispatcher<Timer>>> queuedDispatchers;
{
auto locker = holdLock(sharedLock());
queuedDispatchers = WTFMove(pendingDispatchers());
}
while (!queuedDispatchers.isEmpty()) {
WeakPtr<TaskDispatcher<Timer>> dispatcher = queuedDispatchers.takeFirst();
if (!dispatcher)
continue;
dispatcher->dispatchOneTask();
}
}
Deque<WeakPtr<TaskDispatcher<Timer>>>& TaskDispatcher<Timer>::pendingDispatchers()
{
static LazyNeverDestroyed<Deque<WeakPtr<TaskDispatcher<Timer>>>> dispatchers;
static std::once_flag onceFlag;
std::call_once(onceFlag, [] {
dispatchers.construct();
});
return dispatchers.get();
}
void TaskDispatcher<Timer>::dispatchOneTask()
{
WTF::Function<void()> task;
{
auto locker = holdLock(sharedLock());
ASSERT(!m_pendingTasks.isEmpty());
task = m_pendingTasks.takeFirst();
}
task();
}
}