#include "config.h"
#include "WorkQueue.h"
#include <gio/gio.h>
static const size_t kVisualStudioThreadNameLimit = 31;
void WorkQueue::platformInitialize(const char* name, QOS)
{
m_eventContext = adoptGRef(g_main_context_new());
ASSERT(m_eventContext);
m_eventLoop = adoptGRef(g_main_loop_new(m_eventContext.get(), FALSE));
ASSERT(m_eventLoop);
const char* threadName = g_strrstr(name, ".");
if (threadName)
threadName++;
else
threadName = name;
if (strlen(threadName) > kVisualStudioThreadNameLimit)
threadName += strlen(threadName) - kVisualStudioThreadNameLimit;
m_workQueueThread = createThread(reinterpret_cast<WTF::ThreadFunction>(&WorkQueue::startWorkQueueThread), this, threadName);
}
void WorkQueue::platformInvalidate()
{
MutexLocker locker(m_eventLoopLock);
if (m_eventLoop) {
if (g_main_loop_is_running(m_eventLoop.get()))
g_main_loop_quit(m_eventLoop.get());
m_eventLoop.clear();
}
m_eventContext.clear();
}
void WorkQueue::startWorkQueueThread(WorkQueue* workQueue)
{
workQueue->workQueueThreadBody();
}
void WorkQueue::workQueueThreadBody()
{
g_main_loop_run(m_eventLoop.get());
}
void WorkQueue::registerSocketEventHandler(int fileDescriptor, std::function<void ()> function, std::function<void ()> closeFunction)
{
GRefPtr<GSocket> socket = adoptGRef(g_socket_new_from_fd(fileDescriptor, 0));
ref();
m_socketEventSource.schedule("[WebKit] WorkQueue::SocketEventHandler", [function, closeFunction](GIOCondition condition) {
if (condition & G_IO_HUP || condition & G_IO_ERR || condition & G_IO_NVAL) {
closeFunction();
return GMainLoopSource::Stop;
}
if (condition & G_IO_IN) {
function();
return GMainLoopSource::Continue;
}
ASSERT_NOT_REACHED();
return GMainLoopSource::Stop;
}, socket.get(), G_IO_IN,
[this] { deref(); },
m_eventContext.get());
}
void WorkQueue::unregisterSocketEventHandler(int)
{
m_socketEventSource.cancel();
}
void WorkQueue::dispatch(std::function<void ()> function)
{
ref();
GMainLoopSource::createAndDeleteOnDestroy().schedule("[WebKit] WorkQueue::dispatch", WTF::move(function), G_PRIORITY_DEFAULT,
[this] { deref(); }, m_eventContext.get());
}
void WorkQueue::dispatchAfter(std::chrono::nanoseconds duration, std::function<void ()> function)
{
ref();
GMainLoopSource::createAndDeleteOnDestroy().scheduleAfterDelay("[WebKit] WorkQueue::dispatchAfter", WTF::move(function),
std::chrono::duration_cast<std::chrono::milliseconds>(duration), G_PRIORITY_DEFAULT, [this] { deref(); }, m_eventContext.get());
}