GThreadSafeMainLoopSource.cpp [plain text]
#include "config.h"
#include "GThreadSafeMainLoopSource.h"
#if USE(GLIB)
#include <gio/gio.h>
#include <wtf/glib/GMutexLocker.h>
namespace WTF {
GThreadSafeMainLoopSource::GThreadSafeMainLoopSource()
{
g_rec_mutex_init(&m_mutex);
}
GThreadSafeMainLoopSource::~GThreadSafeMainLoopSource()
{
cancel();
g_rec_mutex_clear(&m_mutex);
}
void GThreadSafeMainLoopSource::cancel()
{
GMutexLocker<GRecMutex> locker(m_mutex);
ASSERT(!m_cancellable || m_status == Dispatching);
g_cancellable_cancel(m_cancellable.get());
m_cancellable = nullptr;
GMainLoopSource::cancel();
}
void GThreadSafeMainLoopSource::schedule(const char* name, std::function<void ()> function, int priority, std::function<void ()> destroyFunction, GMainContext* context)
{
GMutexLocker<GRecMutex> locker(m_mutex);
GMainLoopSource::schedule(name, function, priority, destroyFunction, context);
m_context.cancellable = adoptGRef(g_cancellable_new());
}
void GThreadSafeMainLoopSource::schedule(const char* name, std::function<bool ()> function, int priority, std::function<void ()> destroyFunction, GMainContext* context)
{
GMutexLocker<GRecMutex> locker(m_mutex);
GMainLoopSource::schedule(name, function, priority, destroyFunction, context);
m_context.cancellable = adoptGRef(g_cancellable_new());
}
void GThreadSafeMainLoopSource::scheduleAfterDelay(const char* name, std::function<void ()> function, std::chrono::milliseconds delay, int priority, std::function<void ()> destroyFunction, GMainContext* context)
{
GMutexLocker<GRecMutex> locker(m_mutex);
GMainLoopSource::scheduleAfterDelay(name, function, delay, priority, destroyFunction, context);
m_context.cancellable = adoptGRef(g_cancellable_new());
}
void GThreadSafeMainLoopSource::scheduleAfterDelay(const char* name, std::function<bool ()> function, std::chrono::milliseconds delay, int priority, std::function<void ()> destroyFunction, GMainContext* context)
{
GMutexLocker<GRecMutex> locker(m_mutex);
GMainLoopSource::scheduleAfterDelay(name, function, delay, priority, destroyFunction, context);
m_context.cancellable = adoptGRef(g_cancellable_new());
}
void GThreadSafeMainLoopSource::scheduleAfterDelay(const char* name, std::function<void ()> function, std::chrono::seconds delay, int priority, std::function<void ()> destroyFunction, GMainContext* context)
{
GMutexLocker<GRecMutex> locker(m_mutex);
GMainLoopSource::scheduleAfterDelay(name, function, delay, priority, destroyFunction, context);
m_context.cancellable = adoptGRef(g_cancellable_new());
}
void GThreadSafeMainLoopSource::scheduleAfterDelay(const char* name, std::function<bool ()> function, std::chrono::seconds delay, int priority, std::function<void ()> destroyFunction, GMainContext* context)
{
GMutexLocker<GRecMutex> locker(m_mutex);
GMainLoopSource::scheduleAfterDelay(name, function, delay, priority, destroyFunction, context);
m_context.cancellable = adoptGRef(g_cancellable_new());
}
bool GThreadSafeMainLoopSource::prepareVoidCallback(Context& context)
{
GMutexLocker<GRecMutex> locker(m_mutex);
bool retval = GMainLoopSource::prepareVoidCallback(context);
m_cancellable = context.cancellable;
return retval;
}
void GThreadSafeMainLoopSource::finishVoidCallback()
{
GMutexLocker<GRecMutex> locker(m_mutex);
GMainLoopSource::finishVoidCallback();
m_cancellable = nullptr;
}
void GThreadSafeMainLoopSource::voidCallback()
{
Context context;
if (!prepareVoidCallback(context))
return;
context.voidCallback();
if (g_cancellable_is_cancelled(context.cancellable.get())) {
context.destroySource();
return;
}
finishVoidCallback();
context.destroySource();
}
bool GThreadSafeMainLoopSource::prepareBoolCallback(Context& context)
{
GMutexLocker<GRecMutex> locker(m_mutex);
bool retval = GMainLoopSource::prepareBoolCallback(context);
m_cancellable = context.cancellable;
return retval;
}
void GThreadSafeMainLoopSource::finishBoolCallback(bool retval, Context& context)
{
GMutexLocker<GRecMutex> locker(m_mutex);
GMainLoopSource::finishBoolCallback(retval, context);
m_cancellable = nullptr;
}
bool GThreadSafeMainLoopSource::boolCallback()
{
Context context;
if (!prepareBoolCallback(context))
return Stop;
bool retval = context.boolCallback();
if (g_cancellable_is_cancelled(context.cancellable.get())) {
context.destroySource();
return Stop;
}
finishBoolCallback(retval, context);
if (context.source)
context.destroySource();
return retval;
}
}
#endif // USE(GLIB)