Diff
Modified: releases/WebKitGTK/webkit-2.6/Source/WTF/ChangeLog (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WTF/ChangeLog 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/ChangeLog 2014-10-12 09:18:47 UTC (rev 174638)
@@ -1,3 +1,58 @@
+2014-10-11 Carlos Garcia Campos <[email protected]>
+
+ [GLIB] Split GMainLoopSource moving thread safe implementation to its own class GThreadSafeMainLoopSource
+ https://bugs.webkit.org/show_bug.cgi?id=137485
+
+ Reviewed by Sergio Villar Senin.
+
+ We made GMainLoopSource thread safe, but in most of the cases we
+ know the sources are used by a single thread, which has an impact
+ in the performance (mutex, GCancellable, etc.). The new class
+ GThreadSafeMainLoopSource inherits from GMainLoopSource overriding
+ the new virtual methods and calling the parent for the common code.
+ GMutexLocker now supports recursive mutexes, it's a template that
+ can wrap a GMutex or a GRecMutex. GThreadSafeMainLoopSource uses a
+ recursive mutex using the new GMutexLocker API.
+
+ * wtf/PlatformEfl.cmake: Add new file to compilation.
+ * wtf/PlatformGTK.cmake: Ditto.
+ * wtf/gobject/GMainLoopSource.cpp:
+ (WTF::GMainLoopSource::GMainLoopSource):
+ (WTF::GMainLoopSource::~GMainLoopSource):
+ (WTF::GMainLoopSource::cancel):
+ (WTF::GMainLoopSource::schedule):
+ (WTF::GMainLoopSource::scheduleAfterDelay):
+ (WTF::GMainLoopSource::prepareVoidCallback):
+ (WTF::GMainLoopSource::finishVoidCallback):
+ (WTF::GMainLoopSource::voidCallback):
+ (WTF::GMainLoopSource::prepareBoolCallback):
+ (WTF::GMainLoopSource::finishBoolCallback):
+ (WTF::GMainLoopSource::boolCallback):
+ (WTF::GMainLoopSource::socketCallback):
+ (WTF::GMainLoopSource::cancelWithoutLocking): Deleted.
+ * wtf/gobject/GMainLoopSource.h:
+ * wtf/gobject/GMutexLocker.h:
+ (WTF::MutexWrapper<GMutex>::lock):
+ (WTF::MutexWrapper<GMutex>::unlock):
+ (WTF::MutexWrapper<GRecMutex>::lock):
+ (WTF::MutexWrapper<GRecMutex>::unlock):
+ (WTF::GMutexLocker::GMutexLocker):
+ (WTF::GMutexLocker::lock):
+ (WTF::GMutexLocker::unlock):
+ * wtf/gobject/GThreadSafeMainLoopSource.cpp: Added.
+ (WTF::GThreadSafeMainLoopSource::GThreadSafeMainLoopSource):
+ (WTF::GThreadSafeMainLoopSource::~GThreadSafeMainLoopSource):
+ (WTF::GThreadSafeMainLoopSource::cancel):
+ (WTF::GThreadSafeMainLoopSource::schedule):
+ (WTF::GThreadSafeMainLoopSource::scheduleAfterDelay):
+ (WTF::GThreadSafeMainLoopSource::prepareVoidCallback):
+ (WTF::GThreadSafeMainLoopSource::finishVoidCallback):
+ (WTF::GThreadSafeMainLoopSource::voidCallback):
+ (WTF::GThreadSafeMainLoopSource::prepareBoolCallback):
+ (WTF::GThreadSafeMainLoopSource::finishBoolCallback):
+ (WTF::GThreadSafeMainLoopSource::boolCallback):
+ * wtf/gobject/GThreadSafeMainLoopSource.h: Added.
+
2014-09-18 Carlos Garcia Campos <[email protected]>
[GTK] Dot not allow to create delete-on-destroy GMainLoopSources
Modified: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformEfl.cmake (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformEfl.cmake 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformEfl.cmake 2014-10-12 09:18:47 UTC (rev 174638)
@@ -4,6 +4,7 @@
gobject/GMainLoopSource.cpp
gobject/GRefPtr.cpp
+ gobject/GThreadSafeMainLoopSource.cpp
)
list(APPEND WTF_LIBRARIES
Modified: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformGTK.cmake (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformGTK.cmake 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/PlatformGTK.cmake 2014-10-12 09:18:47 UTC (rev 174638)
@@ -1,6 +1,7 @@
list(APPEND WTF_SOURCES
gobject/GMainLoopSource.cpp
gobject/GRefPtr.cpp
+ gobject/GThreadSafeMainLoopSource.cpp
gobject/GlibUtilities.cpp
gtk/MainThreadGtk.cpp
Modified: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.cpp (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.cpp 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.cpp 2014-10-12 09:18:47 UTC (rev 174638)
@@ -24,12 +24,11 @@
*/
#include "config.h"
+#include "GMainLoopSource.h"
#if USE(GLIB)
-#include "GMainLoopSource.h"
#include <gio/gio.h>
-#include <wtf/gobject/GMutexLocker.h>
namespace WTF {
@@ -42,20 +41,17 @@
: m_deleteOnDestroy(DoNotDeleteOnDestroy)
, m_status(Ready)
{
- g_mutex_init(&m_mutex);
}
GMainLoopSource::GMainLoopSource(DeleteOnDestroyType deleteOnDestroy)
: m_deleteOnDestroy(deleteOnDestroy)
, m_status(Ready)
{
- g_mutex_init(&m_mutex);
}
GMainLoopSource::~GMainLoopSource()
{
cancel();
- g_mutex_clear(&m_mutex);
}
bool GMainLoopSource::isScheduled() const
@@ -70,28 +66,15 @@
void GMainLoopSource::cancel()
{
- GMutexLocker locker(m_mutex);
- cancelWithoutLocking();
-}
-
-void GMainLoopSource::cancelWithoutLocking()
-{
// Delete-on-destroy GMainLoopSource objects can't be cancelled.
if (m_deleteOnDestroy == DeleteOnDestroy)
return;
// A valid context should only be present if GMainLoopSource is in the Scheduled or Dispatching state.
ASSERT(!m_context.source || m_status == Scheduled || m_status == Dispatching);
- // The general cancellable object should only be present if we're currently dispatching this GMainLoopSource.
- ASSERT(!m_cancellable || m_status == Dispatching);
m_status = Ready;
- // The source is perhaps being cancelled in the middle of a callback dispatch.
- // Cancelling this GCancellable object will convey this information to the
- // current execution context when the callback dispatch is finished.
- g_cancellable_cancel(m_cancellable.get());
- m_cancellable = nullptr;
g_cancellable_cancel(m_context.socketCancellable.get());
if (!m_context.source)
@@ -115,13 +98,12 @@
void GMainLoopSource::schedule(const char* name, std::function<void ()> function, int priority, std::function<void ()> destroyFunction, GMainContext* context)
{
- GMutexLocker locker(m_mutex);
- cancelWithoutLocking();
+ cancel();
ASSERT(!m_context.source);
m_context = {
adoptGRef(g_idle_source_new()),
- adoptGRef(g_cancellable_new()),
+ nullptr, // cancellable
nullptr, // socketCancellable
WTF::move(function),
nullptr, // boolCallback
@@ -133,13 +115,12 @@
void GMainLoopSource::schedule(const char* name, std::function<bool ()> function, int priority, std::function<void ()> destroyFunction, GMainContext* context)
{
- GMutexLocker locker(m_mutex);
- cancelWithoutLocking();
+ cancel();
ASSERT(!m_context.source);
m_context = {
adoptGRef(g_idle_source_new()),
- adoptGRef(g_cancellable_new()),
+ nullptr, // cancellable
nullptr, // socketCancellable
nullptr, // voidCallback
WTF::move(function),
@@ -151,14 +132,13 @@
void GMainLoopSource::schedule(const char* name, std::function<bool (GIOCondition)> function, GSocket* socket, GIOCondition condition, std::function<void ()> destroyFunction, GMainContext* context)
{
- GMutexLocker locker(m_mutex);
- cancelWithoutLocking();
+ cancel();
ASSERT(!m_context.source);
GCancellable* socketCancellable = g_cancellable_new();
m_context = {
adoptGRef(g_socket_create_source(socket, condition, socketCancellable)),
- adoptGRef(g_cancellable_new()),
+ nullptr, // cancellable
adoptGRef(socketCancellable),
nullptr, // voidCallback
nullptr, // boolCallback
@@ -187,13 +167,12 @@
void GMainLoopSource::scheduleAfterDelay(const char* name, std::function<void ()> function, std::chrono::milliseconds delay, int priority, std::function<void ()> destroyFunction, GMainContext* context)
{
- GMutexLocker locker(m_mutex);
- cancelWithoutLocking();
+ cancel();
ASSERT(!m_context.source);
m_context = {
adoptGRef(g_timeout_source_new(delay.count())),
- adoptGRef(g_cancellable_new()),
+ nullptr, // cancellable
nullptr, // socketCancellable
WTF::move(function),
nullptr, // boolCallback
@@ -205,13 +184,12 @@
void GMainLoopSource::scheduleAfterDelay(const char* name, std::function<bool ()> function, std::chrono::milliseconds delay, int priority, std::function<void ()> destroyFunction, GMainContext* context)
{
- GMutexLocker locker(m_mutex);
- cancelWithoutLocking();
+ cancel();
ASSERT(!m_context.source);
m_context = {
adoptGRef(g_timeout_source_new(delay.count())),
- adoptGRef(g_cancellable_new()),
+ nullptr, // cancellable
nullptr, // socketCancellable
nullptr, // voidCallback
WTF::move(function),
@@ -223,13 +201,12 @@
void GMainLoopSource::scheduleAfterDelay(const char* name, std::function<void ()> function, std::chrono::seconds delay, int priority, std::function<void ()> destroyFunction, GMainContext* context)
{
- GMutexLocker locker(m_mutex);
- cancelWithoutLocking();
+ cancel();
ASSERT(!m_context.source);
m_context = {
adoptGRef(g_timeout_source_new_seconds(delay.count())),
- adoptGRef(g_cancellable_new()),
+ nullptr, // cancellable
nullptr, // socketCancellable
WTF::move(function),
nullptr, // boolCallback
@@ -241,13 +218,12 @@
void GMainLoopSource::scheduleAfterDelay(const char* name, std::function<bool ()> function, std::chrono::seconds delay, int priority, std::function<void ()> destroyFunction, GMainContext* context)
{
- GMutexLocker locker(m_mutex);
- cancelWithoutLocking();
+ cancel();
ASSERT(!m_context.source);
m_context = {
adoptGRef(g_timeout_source_new_seconds(delay.count())),
- adoptGRef(g_cancellable_new()),
+ nullptr, // cancellable
nullptr, // socketCancellable
nullptr, // voidCallback
WTF::move(function),
@@ -287,86 +263,80 @@
create().scheduleAfterDelay(name, function, delay, priority, destroyFunction, context);
}
-void GMainLoopSource::voidCallback()
+bool GMainLoopSource::prepareVoidCallback(Context& context)
{
- Context context;
+ if (!m_context.source)
+ return false;
- {
- GMutexLocker locker(m_mutex);
- if (!m_context.source)
- return;
+ context = WTF::move(m_context);
- context = WTF::move(m_context);
+ ASSERT(context.voidCallback);
+ ASSERT(m_status == Scheduled);
+ m_status = Dispatching;
- ASSERT(context.voidCallback);
- ASSERT(m_status == Scheduled);
- m_status = Dispatching;
+ return true;
+}
- m_cancellable = context.cancellable;
- }
+void GMainLoopSource::finishVoidCallback()
+{
+ m_status = Ready;
+}
- context.voidCallback();
-
- if (g_cancellable_is_cancelled(context.cancellable.get())) {
- context.destroySource();
+void GMainLoopSource::voidCallback()
+{
+ Context context;
+ if (!prepareVoidCallback(context))
return;
- }
- bool shouldSelfDestruct = false;
- {
- GMutexLocker locker(m_mutex);
- m_status = Ready;
- m_cancellable = nullptr;
- shouldSelfDestruct = m_deleteOnDestroy == DeleteOnDestroy;
+ context.voidCallback();
+ if (m_status != Ready && !m_context.source) {
+ // Switch to Ready if it hasn't been re-scheduled or cancelled.
+ finishVoidCallback();
}
context.destroySource();
- if (shouldSelfDestruct)
+ if (m_deleteOnDestroy == DeleteOnDestroy)
delete this;
}
-bool GMainLoopSource::boolCallback()
+bool GMainLoopSource::prepareBoolCallback(Context& context)
{
- Context context;
+ if (!m_context.source)
+ return false;
- {
- GMutexLocker locker(m_mutex);
- if (!m_context.source)
- return Stop;
+ context = WTF::move(m_context);
- context = WTF::move(m_context);
+ ASSERT(context.boolCallback);
+ ASSERT(m_status == Scheduled || m_status == Dispatching);
+ m_status = Dispatching;
+ return true;
+}
- ASSERT(context.boolCallback);
- ASSERT(m_status == Scheduled || m_status == Dispatching);
- m_status = Dispatching;
+void GMainLoopSource::finishBoolCallback(bool retval, Context& context)
+{
+ // m_status should reflect whether the GMainLoopSource has been rescheduled during dispatch.
+ ASSERT((!m_context.source && m_status == Dispatching) || m_status == Scheduled);
+ if (retval && !m_context.source)
+ m_context = WTF::move(context);
+ else if (!retval)
+ m_status = Ready;
+}
- m_cancellable = context.cancellable;
- }
+bool GMainLoopSource::boolCallback()
+{
+ Context context;
+ if (!prepareBoolCallback(context))
+ return Stop;
bool retval = context.boolCallback();
-
- if (g_cancellable_is_cancelled(context.cancellable.get())) {
- context.destroySource();
- return Stop;
+ if (m_status != Ready && !m_context.source) {
+ // Prepare for a new iteration or switch to Ready if it hasn't been re-scheduled or cancelled.
+ finishBoolCallback(retval, context);
}
- bool shouldSelfDestruct = false;
- {
- GMutexLocker locker(m_mutex);
- m_cancellable = nullptr;
- shouldSelfDestruct = m_deleteOnDestroy == DeleteOnDestroy;
-
- // m_status should reflect whether the GMainLoopSource has been rescheduled during dispatch.
- ASSERT((!m_context.source && m_status == Dispatching) || m_status == Scheduled);
- if (retval && !m_context.source)
- m_context = WTF::move(context);
- else if (!retval)
- m_status = Ready;
- }
-
if (context.source) {
context.destroySource();
- if (shouldSelfDestruct)
+ if (m_deleteOnDestroy == DeleteOnDestroy)
delete this;
}
@@ -375,22 +345,15 @@
bool GMainLoopSource::socketCallback(GIOCondition condition)
{
- Context context;
+ if (!m_context.source)
+ return Stop;
- {
- GMutexLocker locker(m_mutex);
- if (!m_context.source)
- return Stop;
+ Context context = WTF::move(m_context);
- context = WTF::move(m_context);
+ ASSERT(context.socketCallback);
+ ASSERT(m_status == Scheduled || m_status == Dispatching);
+ m_status = Dispatching;
- ASSERT(context.socketCallback);
- ASSERT(m_status == Scheduled || m_status == Dispatching);
- m_status = Dispatching;
-
- m_cancellable = context.cancellable;
- }
-
if (g_cancellable_is_cancelled(context.socketCancellable.get())) {
context.destroySource();
return Stop;
@@ -398,18 +361,9 @@
bool retval = context.socketCallback(condition);
- if (g_cancellable_is_cancelled(context.cancellable.get())) {
- context.destroySource();
- return Stop;
- }
-
- {
- GMutexLocker locker(m_mutex);
- m_cancellable = nullptr;
-
+ if (m_status != Ready && !m_context.source) {
// m_status should reflect whether the GMainLoopSource has been rescheduled during dispatch.
ASSERT((!m_context.source && m_status == Dispatching) || m_status == Scheduled);
-
if (retval && !m_context.source)
m_context = WTF::move(context);
else if (!retval)
Modified: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.h (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.h 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMainLoopSource.h 2014-10-12 09:18:47 UTC (rev 174638)
@@ -26,13 +26,14 @@
#ifndef GMainLoopSource_h
#define GMainLoopSource_h
+#if USE(GLIB)
+
#include <functional>
#include <glib.h>
#include <wtf/Noncopyable.h>
#include <wtf/gobject/GRefPtr.h>
typedef struct _GSocket GSocket;
-typedef union _GMutex GMutex;
namespace WTF {
@@ -41,7 +42,7 @@
WTF_MAKE_FAST_ALLOCATED;
public:
WTF_EXPORT_PRIVATE GMainLoopSource();
- WTF_EXPORT_PRIVATE ~GMainLoopSource();
+ WTF_EXPORT_PRIVATE virtual ~GMainLoopSource();
static const bool Stop = false;
static const bool Continue = true;
@@ -49,14 +50,15 @@
WTF_EXPORT_PRIVATE bool isScheduled() const;
WTF_EXPORT_PRIVATE bool isActive() const;
- WTF_EXPORT_PRIVATE void schedule(const char* name, std::function<void()>, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
- WTF_EXPORT_PRIVATE void schedule(const char* name, std::function<bool()>, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
+ WTF_EXPORT_PRIVATE virtual void schedule(const char* name, std::function<void()>, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
+ WTF_EXPORT_PRIVATE virtual void schedule(const char* name, std::function<bool()>, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
+ WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function<void()>, std::chrono::milliseconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
+ WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function<bool()>, std::chrono::milliseconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
+ WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function<void()>, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
+ WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function<bool()>, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
+ WTF_EXPORT_PRIVATE virtual void cancel();
+
WTF_EXPORT_PRIVATE void schedule(const char* name, std::function<bool(GIOCondition)>, GSocket*, GIOCondition, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
- WTF_EXPORT_PRIVATE void scheduleAfterDelay(const char* name, std::function<void()>, std::chrono::milliseconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
- WTF_EXPORT_PRIVATE void scheduleAfterDelay(const char* name, std::function<bool()>, std::chrono::milliseconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
- WTF_EXPORT_PRIVATE void scheduleAfterDelay(const char* name, std::function<void()>, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
- WTF_EXPORT_PRIVATE void scheduleAfterDelay(const char* name, std::function<bool()>, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
- WTF_EXPORT_PRIVATE void cancel();
static void scheduleAndDeleteOnDestroy(const char* name, std::function<void()>, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
static void scheduleAndDeleteOnDestroy(const char* name, std::function<bool()>, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
@@ -65,51 +67,58 @@
static void scheduleAfterDelayAndDeleteOnDestroy(const char* name, std::function<void()>, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
static void scheduleAfterDelayAndDeleteOnDestroy(const char* name, std::function<bool()>, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr);
+protected:
+ enum Status { Ready, Scheduled, Dispatching };
+
+ struct Context {
+ Context() = default;
+ Context(Context&&) = default;
+ Context& operator=(Context&&) = default;
+
+ void destroySource();
+
+ GRefPtr<GSource> source;
+ GRefPtr<GCancellable> cancellable;
+ GRefPtr<GCancellable> socketCancellable;
+ std::function<void ()> voidCallback;
+ std::function<bool ()> boolCallback;
+ std::function<bool (GIOCondition)> socketCallback;
+ std::function<void ()> destroyCallback;
+ };
+
+ virtual void voidCallback();
+ virtual bool boolCallback();
+
+ virtual bool prepareVoidCallback(Context&);
+ virtual void finishVoidCallback();
+ virtual bool prepareBoolCallback(Context&);
+ virtual void finishBoolCallback(bool retval, Context&);
+
private:
static GMainLoopSource& create();
enum DeleteOnDestroyType { DeleteOnDestroy, DoNotDeleteOnDestroy };
GMainLoopSource(DeleteOnDestroyType);
- enum Status { Ready, Scheduled, Dispatching };
-
- void cancelWithoutLocking();
void scheduleIdleSource(const char* name, GSourceFunc, int priority, GMainContext*);
void scheduleTimeoutSource(const char* name, GSourceFunc, int priority, GMainContext*);
- void voidCallback();
- bool boolCallback();
bool socketCallback(GIOCondition);
- void destroy();
-
static gboolean voidSourceCallback(GMainLoopSource*);
static gboolean boolSourceCallback(GMainLoopSource*);
static gboolean socketSourceCallback(GSocket*, GIOCondition, GMainLoopSource*);
DeleteOnDestroyType m_deleteOnDestroy;
+
+protected:
+ Context m_context;
Status m_status;
- GMutex m_mutex;
- GRefPtr<GCancellable> m_cancellable;
-
- struct Context {
- Context() = default;
- Context(Context&&) = default;
- Context& operator=(Context&&) = default;
-
- void destroySource();
-
- GRefPtr<GSource> source;
- GRefPtr<GCancellable> cancellable;
- GRefPtr<GCancellable> socketCancellable;
- std::function<void ()> voidCallback;
- std::function<bool ()> boolCallback;
- std::function<bool (GIOCondition)> socketCallback;
- std::function<void ()> destroyCallback;
- } m_context;
};
} // namespace WTF
using WTF::GMainLoopSource;
+#endif // USE(GLIB)
+
#endif // GMainLoopSource_h
Modified: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMutexLocker.h (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMutexLocker.h 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GMutexLocker.h 2014-10-12 09:18:47 UTC (rev 174638)
@@ -27,10 +27,40 @@
namespace WTF {
+template<typename T>
+struct MutexWrapper;
+
+template<>
+struct MutexWrapper<GMutex> {
+ static void lock(GMutex* mutex)
+ {
+ g_mutex_lock(mutex);
+ }
+
+ static void unlock(GMutex* mutex)
+ {
+ g_mutex_unlock(mutex);
+ }
+};
+
+template<>
+struct MutexWrapper<GRecMutex> {
+ static void lock(GRecMutex* mutex)
+ {
+ g_rec_mutex_lock(mutex);
+ }
+
+ static void unlock(GRecMutex* mutex)
+ {
+ g_rec_mutex_unlock(mutex);
+ }
+};
+
+template<typename T>
class GMutexLocker {
WTF_MAKE_NONCOPYABLE(GMutexLocker);
public:
- explicit GMutexLocker(GMutex& mutex)
+ explicit GMutexLocker(T& mutex)
: m_mutex(mutex)
, m_locked(false)
{
@@ -44,22 +74,24 @@
void lock()
{
- if (!m_locked) {
- g_mutex_lock(&m_mutex);
- m_locked = true;
- }
+ if (m_locked)
+ return;
+
+ MutexWrapper<T>::lock(&m_mutex);
+ m_locked = true;
}
void unlock()
{
- if (m_locked) {
- m_locked = false;
- g_mutex_unlock(&m_mutex);
- }
+ if (!m_locked)
+ return;
+
+ m_locked = false;
+ MutexWrapper<T>::unlock(&m_mutex);
}
private:
- GMutex& m_mutex;
+ T& m_mutex;
bool m_locked;
};
Added: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.cpp (0 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.cpp (rev 0)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.cpp 2014-10-12 09:18:47 UTC (rev 174638)
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GThreadSafeMainLoopSource.h"
+
+#if USE(GLIB)
+
+#include <gio/gio.h>
+#include <wtf/gobject/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);
+
+ // The general cancellable object should only be present if we're currently dispatching this GMainLoopSource.
+ ASSERT(!m_cancellable || m_status == Dispatching);
+
+ // The source is perhaps being cancelled in the middle of a callback dispatch.
+ // Cancelling this GCancellable object will convey this information to the
+ // current execution context when the callback dispatch is finished.
+ 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;
+}
+
+} // namespace WTF
+
+#endif // USE(GLIB)
Added: releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.h (0 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.h (rev 0)
+++ releases/WebKitGTK/webkit-2.6/Source/WTF/wtf/gobject/GThreadSafeMainLoopSource.h 2014-10-12 09:18:47 UTC (rev 174638)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GThreadSafeMainLoopSource_h
+#define GThreadSafeMainLoopSource_h
+
+#if USE(GLIB)
+
+#include <wtf/gobject/GMainLoopSource.h>
+
+typedef struct _GRecMutex GRecMutex;
+
+namespace WTF {
+
+class GThreadSafeMainLoopSource final : public GMainLoopSource {
+ WTF_MAKE_NONCOPYABLE(GThreadSafeMainLoopSource);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ WTF_EXPORT_PRIVATE GThreadSafeMainLoopSource();
+ WTF_EXPORT_PRIVATE virtual ~GThreadSafeMainLoopSource();
+
+ WTF_EXPORT_PRIVATE virtual void schedule(const char* name, std::function<void()>, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr) override;
+ WTF_EXPORT_PRIVATE virtual void schedule(const char* name, std::function<bool()>, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr) override;
+ WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function<void()>, std::chrono::milliseconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr) override;
+ WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function<bool()>, std::chrono::milliseconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr) override;
+ WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function<void()>, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr) override;
+ WTF_EXPORT_PRIVATE virtual void scheduleAfterDelay(const char* name, std::function<bool()>, std::chrono::seconds, int priority = G_PRIORITY_DEFAULT, std::function<void()> destroyFunction = nullptr, GMainContext* = nullptr) override;
+ WTF_EXPORT_PRIVATE virtual void cancel() override;
+
+private:
+ virtual void voidCallback() override;
+ virtual bool boolCallback() override;
+
+ virtual bool prepareVoidCallback(Context&) override;
+ virtual void finishVoidCallback() override;
+ virtual bool prepareBoolCallback(Context&) override;
+ virtual void finishBoolCallback(bool retval, Context&) override;
+
+ GRecMutex m_mutex;
+ GRefPtr<GCancellable> m_cancellable;
+};
+
+} // namespace WTF
+
+using WTF::GThreadSafeMainLoopSource;
+
+#endif // USE(GLIB)
+
+#endif // GThreadSafeMainLoopSource_h
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog 2014-10-12 09:18:47 UTC (rev 174638)
@@ -1,3 +1,52 @@
+2014-10-11 Carlos Garcia Campos <[email protected]>
+
+ [GLIB] Split GMainLoopSource moving thread safe implementation to its own class GThreadSafeMainLoopSource
+ https://bugs.webkit.org/show_bug.cgi?id=137485
+
+ Reviewed by Sergio Villar Senin.
+
+ Use GThreadSafeMainLoopSource for GStreamer sources, since they
+ can be used from different threads. Also update GMutexLocker
+ usages, since it's now a template.
+
+ * platform/audio/gstreamer/AudioFileReaderGStreamer.cpp:
+ (WebCore::AudioFileReader::createBus):
+ * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
+ (WebCore::MediaPlayerPrivateGStreamerBase::updateTexture):
+ (WebCore::MediaPlayerPrivateGStreamerBase::triggerRepaint):
+ (WebCore::MediaPlayerPrivateGStreamerBase::paint):
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
+ * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h:
+ * platform/graphics/gstreamer/VideoSinkGStreamer.cpp:
+ (webkitVideoSinkTimeoutCallback):
+ (webkitVideoSinkRender):
+ (unlockBufferMutex):
+ (webkitVideoSinkUnlockStop):
+ (webkitVideoSinkStart):
+ * platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp:
+ * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
+ (webKitWebSrcGetProperty):
+ (webKitWebSrcStop):
+ (webKitWebSrcStart):
+ (webKitWebSrcChangeState):
+ (webKitWebSrcQueryWithParent):
+ (webKitWebSrcGetUri):
+ (webKitWebSrcSetUri):
+ (webKitWebSrcNeedDataMainCb):
+ (webKitWebSrcNeedDataCb):
+ (webKitWebSrcEnoughDataMainCb):
+ (webKitWebSrcEnoughDataCb):
+ (webKitWebSrcSeekDataCb):
+ (webKitWebSrcSetMediaPlayer):
+ (StreamingClient::createReadBuffer):
+ (StreamingClient::handleResponseReceived):
+ (StreamingClient::handleDataReceived):
+ (StreamingClient::handleNotifyFinished):
+ (ResourceHandleStreamingClient::wasBlocked):
+ (ResourceHandleStreamingClient::cannotShowURL):
+
2014-10-05 Carlos Garcia Campos <[email protected]>
[GTK] Do not generate a symlink in derived sources for every header in WebCore/bindings/gobject
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp 2014-10-12 09:18:47 UTC (rev 174638)
@@ -31,8 +31,8 @@
#include <gst/gst.h>
#include <gst/pbutils/pbutils.h>
#include <wtf/Noncopyable.h>
-#include <wtf/gobject/GMainLoopSource.h>
#include <wtf/gobject/GRefPtr.h>
+#include <wtf/gobject/GThreadSafeMainLoopSource.h>
#include <wtf/gobject/GUniquePtr.h>
namespace WebCore {
@@ -334,7 +334,7 @@
m_loop = adoptGRef(g_main_loop_new(context.get(), FALSE));
// Start the pipeline processing just after the loop is started.
- GMainLoopSource source;
+ GThreadSafeMainLoopSource source;
source.schedule("[WebKit] AudioFileReader::decodeAudioForBusCreation", std::function<void()>(std::bind(&AudioFileReader::decodeAudioForBusCreation, this)), G_PRIORITY_DEFAULT, nullptr, context.get());
g_main_loop_run(m_loop.get());
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h 2014-10-12 09:18:47 UTC (rev 174638)
@@ -31,7 +31,7 @@
#include "GRefPtrGStreamer.h"
#include "InbandTextTrackPrivate.h"
#include "TrackPrivateBaseGStreamer.h"
-#include <wtf/gobject/GMainLoopSource.h>
+#include <wtf/gobject/GThreadSafeMainLoopSource.h>
namespace WebCore {
@@ -62,8 +62,8 @@
private:
InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad>);
- GMainLoopSource m_sampleTimerHandler;
- GMainLoopSource m_streamTimerHandler;
+ GThreadSafeMainLoopSource m_sampleTimerHandler;
+ GThreadSafeMainLoopSource m_streamTimerHandler;
gulong m_eventProbe;
Vector<GRefPtr<GstSample> > m_pendingSamples;
String m_streamId;
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h 2014-10-12 09:18:47 UTC (rev 174638)
@@ -33,7 +33,7 @@
#include <gst/gst.h>
#include <gst/pbutils/install-plugins.h>
#include <wtf/Forward.h>
-#include <wtf/gobject/GMainLoopSource.h>
+#include <wtf/gobject/GThreadSafeMainLoopSource.h>
#if ENABLE(VIDEO_TRACK) && USE(GSTREAMER_MPEGTS)
#include <wtf/text/AtomicStringHash.h>
@@ -202,11 +202,11 @@
bool m_volumeAndMuteInitialized;
bool m_hasVideo;
bool m_hasAudio;
- GMainLoopSource m_audioTimerHandler;
- GMainLoopSource m_textTimerHandler;
- GMainLoopSource m_videoTimerHandler;
- GMainLoopSource m_videoCapsTimerHandler;
- GMainLoopSource m_readyTimerHandler;
+ GThreadSafeMainLoopSource m_audioTimerHandler;
+ GThreadSafeMainLoopSource m_textTimerHandler;
+ GThreadSafeMainLoopSource m_videoTimerHandler;
+ GThreadSafeMainLoopSource m_videoCapsTimerHandler;
+ GThreadSafeMainLoopSource m_readyTimerHandler;
mutable long m_totalBytes;
URL m_url;
bool m_preservesPitch;
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp 2014-10-12 09:18:47 UTC (rev 174638)
@@ -275,7 +275,7 @@
#if USE(TEXTURE_MAPPER_GL) && !USE(COORDINATED_GRAPHICS)
PassRefPtr<BitmapTexture> MediaPlayerPrivateGStreamerBase::updateTexture(TextureMapper* textureMapper)
{
- GMutexLocker lock(m_bufferMutex);
+ GMutexLocker<GMutex> lock(m_bufferMutex);
if (!m_buffer)
return nullptr;
@@ -325,7 +325,7 @@
g_return_if_fail(GST_IS_BUFFER(buffer));
{
- GMutexLocker lock(m_bufferMutex);
+ GMutexLocker<GMutex> lock(m_bufferMutex);
gst_buffer_replace(&m_buffer, buffer);
}
@@ -357,7 +357,7 @@
if (!m_player->visible())
return;
- GMutexLocker lock(m_bufferMutex);
+ GMutexLocker<GMutex> lock(m_bufferMutex);
if (!m_buffer)
return;
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h 2014-10-12 09:18:47 UTC (rev 174638)
@@ -30,7 +30,7 @@
#include <glib.h>
#include <wtf/Forward.h>
-#include <wtf/gobject/GMainLoopSource.h>
+#include <wtf/gobject/GThreadSafeMainLoopSource.h>
#if USE(TEXTURE_MAPPER_GL) && !USE(COORDINATED_GRAPHICS)
#include "TextureMapperPlatformLayer.h"
@@ -125,8 +125,8 @@
IntSize m_size;
GMutex m_bufferMutex;
GstBuffer* m_buffer;
- GMainLoopSource m_volumeTimerHandler;
- GMainLoopSource m_muteTimerHandler;
+ GThreadSafeMainLoopSource m_volumeTimerHandler;
+ GThreadSafeMainLoopSource m_muteTimerHandler;
unsigned long m_repaintHandler;
unsigned long m_volumeSignalHandler;
unsigned long m_muteSignalHandler;
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h 2014-10-12 09:18:47 UTC (rev 174638)
@@ -30,7 +30,7 @@
#include "GRefPtrGStreamer.h"
#include <wtf/ThreadingPrimitives.h>
-#include <wtf/gobject/GMainLoopSource.h>
+#include <wtf/gobject/GThreadSafeMainLoopSource.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -70,8 +70,8 @@
bool getTag(GstTagList* tags, const gchar* tagName, StringType& value);
TrackPrivateBase* m_owner;
- GMainLoopSource m_activeTimerHandler;
- GMainLoopSource m_tagTimerHandler;
+ GThreadSafeMainLoopSource m_activeTimerHandler;
+ GThreadSafeMainLoopSource m_tagTimerHandler;
Mutex m_tagMutex;
GRefPtr<GstTagList> m_tags;
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp 2014-10-12 09:18:47 UTC (rev 174638)
@@ -36,8 +36,8 @@
#include <gst/gst.h>
#include <gst/video/gstvideometa.h>
#include <wtf/OwnPtr.h>
-#include <wtf/gobject/GMainLoopSource.h>
#include <wtf/gobject/GMutexLocker.h>
+#include <wtf/gobject/GThreadSafeMainLoopSource.h>
using namespace WebCore;
@@ -88,7 +88,7 @@
}
GstBuffer* buffer;
- GMainLoopSource timeoutSource;
+ GThreadSafeMainLoopSource timeoutSource;
GMutex bufferMutex;
GCond dataCondition;
@@ -121,7 +121,7 @@
{
WebKitVideoSinkPrivate* priv = sink->priv;
- GMutexLocker lock(priv->bufferMutex);
+ GMutexLocker<GMutex> lock(priv->bufferMutex);
GstBuffer* buffer = priv->buffer;
priv->buffer = 0;
@@ -140,7 +140,7 @@
WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(baseSink);
WebKitVideoSinkPrivate* priv = sink->priv;
- GMutexLocker lock(priv->bufferMutex);
+ GMutexLocker<GMutex> lock(priv->bufferMutex);
if (priv->unlocked)
return GST_FLOW_OK;
@@ -257,7 +257,7 @@
static void unlockBufferMutex(WebKitVideoSinkPrivate* priv)
{
- GMutexLocker lock(priv->bufferMutex);
+ GMutexLocker<GMutex> lock(priv->bufferMutex);
if (priv->buffer) {
gst_buffer_unref(priv->buffer);
@@ -283,7 +283,7 @@
WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(baseSink)->priv;
{
- GMutexLocker lock(priv->bufferMutex);
+ GMutexLocker<GMutex> lock(priv->bufferMutex);
priv->unlocked = false;
}
@@ -308,7 +308,7 @@
{
WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(baseSink)->priv;
- GMutexLocker lock(priv->bufferMutex);
+ GMutexLocker<GMutex> lock(priv->bufferMutex);
priv->unlocked = false;
return TRUE;
}
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp 2014-10-12 09:18:47 UTC (rev 174638)
@@ -30,7 +30,7 @@
#include <gst/app/gstappsrc.h>
#include <gst/gst.h>
#include <gst/pbutils/missing-plugins.h>
-#include <wtf/gobject/GMainLoopSource.h>
+#include <wtf/gobject/GThreadSafeMainLoopSource.h>
#include <wtf/gobject/GUniquePtr.h>
#include <wtf/text/CString.h>
@@ -44,11 +44,11 @@
guint64 size;
gboolean paused;
- GMainLoopSource start;
- GMainLoopSource stop;
- GMainLoopSource needData;
- GMainLoopSource enoughData;
- GMainLoopSource seek;
+ GThreadSafeMainLoopSource start;
+ GThreadSafeMainLoopSource stop;
+ GThreadSafeMainLoopSource needData;
+ GThreadSafeMainLoopSource enoughData;
+ GThreadSafeMainLoopSource seek;
guint64 requestedOffset;
} Source;
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp 2014-10-12 09:18:47 UTC (rev 174638)
@@ -43,9 +43,9 @@
#include <gst/gst.h>
#include <gst/pbutils/missing-plugins.h>
#include <wtf/Noncopyable.h>
-#include <wtf/gobject/GMainLoopSource.h>
#include <wtf/gobject/GMutexLocker.h>
#include <wtf/gobject/GRefPtr.h>
+#include <wtf/gobject/GThreadSafeMainLoopSource.h>
#include <wtf/gobject/GUniquePtr.h>
#include <wtf/text/CString.h>
@@ -139,11 +139,11 @@
guint64 requestedOffset;
- GMainLoopSource startSource;
- GMainLoopSource stopSource;
- GMainLoopSource needDataSource;
- GMainLoopSource enoughDataSource;
- GMainLoopSource seekSource;
+ GThreadSafeMainLoopSource startSource;
+ GThreadSafeMainLoopSource stopSource;
+ GThreadSafeMainLoopSource needDataSource;
+ GThreadSafeMainLoopSource enoughDataSource;
+ GThreadSafeMainLoopSource seekSource;
GRefPtr<GstBuffer> buffer;
@@ -352,7 +352,7 @@
WebKitWebSrc* src = ""
WebKitWebSrcPrivate* priv = src->priv;
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
switch (propID) {
case PROP_IRADIO_NAME:
g_value_set_string(value, priv->iradioName);
@@ -391,7 +391,7 @@
ASSERT(isMainThread());
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
bool seeking = priv->seekSource.isActive();
@@ -447,7 +447,7 @@
ASSERT(isMainThread());
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
priv->corsAccessCheck = CORSNoCheck;
@@ -539,7 +539,7 @@
return ret;
}
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
switch (transition) {
case GST_STATE_CHANGE_READY_TO_PAUSED:
GST_DEBUG_OBJECT(src, "READY->PAUSED");
@@ -574,7 +574,7 @@
gst_query_parse_duration(query, &format, NULL);
GST_DEBUG_OBJECT(src, "duration query in format %s", gst_format_get_name(format));
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
if (format == GST_FORMAT_BYTES && src->priv->size > 0) {
gst_query_set_duration(query, format, src->priv->size);
result = TRUE;
@@ -582,7 +582,7 @@
break;
}
case GST_QUERY_URI: {
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
gst_query_set_uri(query, src->priv->uri);
result = TRUE;
break;
@@ -623,7 +623,7 @@
WebKitWebSrc* src = ""
gchar* ret;
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
ret = g_strdup(src->priv->uri);
return ret;
}
@@ -638,7 +638,7 @@
return FALSE;
}
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
g_free(priv->uri);
priv->uri = 0;
@@ -674,7 +674,7 @@
ASSERT(isMainThread());
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
priv->paused = FALSE;
locker.unlock();
@@ -689,7 +689,7 @@
GST_DEBUG_OBJECT(src, "Need more data: %u", length);
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
if (priv->needDataSource.isScheduled() || !priv->paused)
return;
@@ -704,7 +704,7 @@
ASSERT(isMainThread());
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
priv->paused = TRUE;
locker.unlock();
@@ -719,7 +719,7 @@
GST_DEBUG_OBJECT(src, "Have enough data");
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
if (priv->enoughDataSource.isScheduled() || priv->paused)
return;
@@ -742,7 +742,7 @@
WebKitWebSrcPrivate* priv = src->priv;
GST_DEBUG_OBJECT(src, "Seeking to offset: %" G_GUINT64_FORMAT, offset);
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
if (offset == priv->offset && priv->requestedOffset == priv->offset)
return TRUE;
@@ -761,7 +761,7 @@
void webKitWebSrcSetMediaPlayer(WebKitWebSrc* src, WebCore::MediaPlayer* player)
{
ASSERT(player);
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
src->priv->player = player;
}
@@ -791,7 +791,7 @@
mapGstBuffer(buffer);
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
priv->buffer = adoptGRef(buffer);
locker.unlock();
@@ -817,7 +817,7 @@
return;
}
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
priv->corsAccessCheck = corsAccessCheck;
@@ -916,7 +916,7 @@
WebKitWebSrc* src = ""
WebKitWebSrcPrivate* priv = src->priv;
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
GST_LOG_OBJECT(src, "Have %lld bytes of data", priv->buffer ? static_cast<long long>(gst_buffer_get_size(priv->buffer.get())) : length);
@@ -985,7 +985,7 @@
GST_DEBUG_OBJECT(src, "Have EOS");
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
if (!priv->seekSource.isActive()) {
locker.unlock();
gst_app_src_end_of_stream(priv->appsrc);
@@ -1144,7 +1144,7 @@
GST_ERROR_OBJECT(src, "Request was blocked");
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
uri.reset(g_strdup(src->priv->uri));
locker.unlock();
@@ -1158,7 +1158,7 @@
GST_ERROR_OBJECT(src, "Cannot show URL");
- GMutexLocker locker(*GST_OBJECT_GET_LOCK(src));
+ GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
uri.reset(g_strdup(src->priv->uri));
locker.unlock();
Modified: releases/WebKitGTK/webkit-2.6/Tools/ChangeLog (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Tools/ChangeLog 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Tools/ChangeLog 2014-10-12 09:18:47 UTC (rev 174638)
@@ -1,3 +1,27 @@
+2014-10-11 Carlos Garcia Campos <[email protected]>
+
+ [GLIB] Split GMainLoopSource moving thread safe implementation to its own class GThreadSafeMainLoopSource
+ https://bugs.webkit.org/show_bug.cgi?id=137485
+
+ Reviewed by Sergio Villar Senin.
+
+ Update GMainLoopSource tests. Most of the tests are now run twice,
+ first with a GMainLoopSource and then with a
+ GThreadSafeMainLoopSource, since both should have the same
+ behaviour. The threading test uses GThreadSafeMainLoopSource and
+ the delete on destroy test uses GMainLoopSource. The tests
+ themselves haven't changed, since there's no change in behaviour.
+
+ * TestWebKitAPI/Tests/WTF/gobject/GMainLoopSource.cpp:
+ (TestWebKitAPI::GMainLoopSourceTest::source):
+ (TestWebKitAPI::basicRescheduling):
+ (TestWebKitAPI::TEST):
+ (TestWebKitAPI::reentrantRescheduling):
+ (TestWebKitAPI::cancelRepeatingSourceDuringDispatch):
+ (TestWebKitAPI::basicDestroyCallbacks):
+ (TestWebKitAPI::destroyCallbacksAfterCancellingDuringDispatch):
+ (TestWebKitAPI::destroyCallbacksAfterReschedulingDuringDispatch):
+
2014-10-08 Carlos Garcia Campos <[email protected]>
[GTK] Make forwarding headers generation depend on source code
Modified: releases/WebKitGTK/webkit-2.6/Tools/TestWebKitAPI/Tests/WTF/gobject/GMainLoopSource.cpp (174637 => 174638)
--- releases/WebKitGTK/webkit-2.6/Tools/TestWebKitAPI/Tests/WTF/gobject/GMainLoopSource.cpp 2014-10-12 08:35:34 UTC (rev 174637)
+++ releases/WebKitGTK/webkit-2.6/Tools/TestWebKitAPI/Tests/WTF/gobject/GMainLoopSource.cpp 2014-10-12 09:18:47 UTC (rev 174638)
@@ -19,11 +19,12 @@
#include "config.h"
-#include <wtf/gobject/GMainLoopSource.h>
+#include <wtf/gobject/GThreadSafeMainLoopSource.h>
#include <stdio.h>
namespace TestWebKitAPI {
+template <typename T>
class GMainLoopSourceTest {
public:
GMainLoopSourceTest()
@@ -56,21 +57,16 @@
g_main_loop_quit(m_mainLoop);
}
- GMainLoopSource& source() { return m_source; }
+ T& source() { return m_source; }
private:
GMainLoop* m_mainLoop;
- GMainLoopSource m_source;
+ T m_source;
};
-TEST(WTF_GMainLoopSource, BasicRescheduling)
+template <typename T>
+static void basicRescheduling(T& context)
{
- struct TestingContext {
- GMainLoopSourceTest test;
- bool finishedFirstTask = false;
- bool finishedSecondTask = false;
- } context;
-
EXPECT_TRUE(!context.test.source().isActive());
context.test.source().schedule("[Test] FirstTask", [&] {
@@ -94,14 +90,26 @@
EXPECT_TRUE(context.finishedSecondTask);
}
-TEST(WTF_GMainLoopSource, ReentrantRescheduling)
+TEST(WTF_GMainLoopSource, BasicRescheduling)
{
struct TestingContext {
- GMainLoopSourceTest test;
+ GMainLoopSourceTest<GMainLoopSource> test;
bool finishedFirstTask = false;
bool finishedSecondTask = false;
} context;
+ basicRescheduling<TestingContext>(context);
+ struct ThreadSafeTestingContext {
+ GMainLoopSourceTest<GThreadSafeMainLoopSource> test;
+ bool finishedFirstTask = false;
+ bool finishedSecondTask = false;
+ } threadSafeContext;
+ basicRescheduling<ThreadSafeTestingContext>(threadSafeContext);
+}
+
+template <typename T>
+static void reentrantRescheduling(T& context)
+{
EXPECT_TRUE(!context.test.source().isActive());
context.test.source().schedule("[Test] FirstTask", [&] {
@@ -127,10 +135,27 @@
EXPECT_TRUE(context.finishedSecondTask);
}
+TEST(WTF_GMainLoopSource, ReentrantRescheduling)
+{
+ struct TestingContext {
+ GMainLoopSourceTest<GMainLoopSource> test;
+ bool finishedFirstTask = false;
+ bool finishedSecondTask = false;
+ } context;
+ reentrantRescheduling<TestingContext>(context);
+
+ struct ThreadSafeTestingContext {
+ GMainLoopSourceTest<GThreadSafeMainLoopSource> test;
+ bool finishedFirstTask = false;
+ bool finishedSecondTask = false;
+ } threadSafeContext;
+ reentrantRescheduling<ThreadSafeTestingContext>(threadSafeContext);
+}
+
TEST(WTF_GMainLoopSource, ReschedulingFromDifferentThread)
{
struct TestingContext {
- GMainLoopSourceTest test;
+ GMainLoopSourceTest<GThreadSafeMainLoopSource> test;
bool finishedFirstTask;
bool finishedSecondTask;
} context;
@@ -198,13 +223,9 @@
g_main_loop_unref(loop);
}
-TEST(WTF_GMainLoopSource, CancelRepeatingSourceDuringDispatch)
+template <typename T>
+static void cancelRepeatingSourceDuringDispatch(T& context)
{
- struct TestingContext {
- GMainLoopSourceTest test;
- unsigned callCount = 0;
- } context;
-
EXPECT_TRUE(!context.test.source().isActive());
context.test.source().schedule("[Test] RepeatingTask",
@@ -225,16 +246,26 @@
EXPECT_EQ(3, context.callCount);
}
-TEST(WTF_GMainLoopSource, BasicDestroyCallbacks)
+TEST(WTF_GMainLoopSource, CancelRepeatingSourceDuringDispatch)
{
struct TestingContext {
- GMainLoopSourceTest test;
- bool callbackCalled = false;
- bool destroyCallbackCalled = false;
- };
+ GMainLoopSourceTest<GMainLoopSource> test;
+ unsigned callCount = 0;
+ } context;
+ cancelRepeatingSourceDuringDispatch<TestingContext>(context);
+ struct ThreadSafeTestingContext {
+ GMainLoopSourceTest<GThreadSafeMainLoopSource> test;
+ unsigned callCount = 0;
+ } threadSafeContext;
+ cancelRepeatingSourceDuringDispatch<ThreadSafeTestingContext>(threadSafeContext);
+}
+
+template <typename T>
+static void basicDestroyCallbacks()
+{
{
- TestingContext context;
+ T context;
EXPECT_TRUE(!context.test.source().isActive());
context.test.source().schedule("[Test] DestroyCallback",
[&] {
@@ -256,7 +287,7 @@
}
{
- TestingContext context;
+ T context;
EXPECT_TRUE(!context.test.source().isActive());
context.test.source().schedule("[Test] DestroyCallback",
std::function<bool ()>([&] {
@@ -279,16 +310,28 @@
}
}
-TEST(WTF_GMainLoopSource, DestroyCallbacksAfterCancellingDuringDispatch)
+TEST(WTF_GMainLoopSource, BasicDestroyCallbacks)
{
struct TestingContext {
- GMainLoopSourceTest test;
- unsigned callbackCallCount= 0;
+ GMainLoopSourceTest<GMainLoopSource> test;
+ bool callbackCalled = false;
bool destroyCallbackCalled = false;
};
+ basicDestroyCallbacks<TestingContext>();
+ struct ThreadSafeTestingContext {
+ GMainLoopSourceTest<GThreadSafeMainLoopSource> test;
+ bool callbackCalled = false;
+ bool destroyCallbackCalled = false;
+ };
+ basicDestroyCallbacks<ThreadSafeTestingContext>();
+}
+
+template <typename T>
+static void destroyCallbacksAfterCancellingDuringDispatch()
+{
{
- TestingContext context;
+ T context;
EXPECT_TRUE(!context.test.source().isActive());
context.test.source().schedule("[Test] DestroyCallback",
[&] {
@@ -312,7 +355,7 @@
}
{
- TestingContext context;
+ T context;
EXPECT_TRUE(!context.test.source().isActive());
context.test.source().schedule("[Test] DestroyCallback",
std::function<bool ()>([&] {
@@ -337,18 +380,28 @@
}
}
-TEST(WTF_GMainLoopSource, DestroyCallbacksAfterReschedulingDuringDispatch)
+TEST(WTF_GMainLoopSource, DestroyCallbacksAfterCancellingDuringDispatch)
{
struct TestingContext {
- GMainLoopSourceTest test;
- unsigned firstCallbackCallCount = 0;
- bool firstDestroyCallbackCalled = false;
- unsigned secondCallbackCallCount = 0;
- bool secondDestroyCallbackCalled = false;
+ GMainLoopSourceTest<GMainLoopSource> test;
+ unsigned callbackCallCount= 0;
+ bool destroyCallbackCalled = false;
};
+ destroyCallbacksAfterCancellingDuringDispatch<TestingContext>();
+ struct ThreadSafeTestingContext {
+ GMainLoopSourceTest<GThreadSafeMainLoopSource> test;
+ unsigned callbackCallCount= 0;
+ bool destroyCallbackCalled = false;
+ };
+ destroyCallbacksAfterCancellingDuringDispatch<ThreadSafeTestingContext>();
+}
+
+template <typename T>
+static void destroyCallbacksAfterReschedulingDuringDispatch()
+{
{
- TestingContext context;
+ T context;
EXPECT_TRUE(!context.test.source().isActive());
context.test.source().schedule("[Test] BaseCallback",
[&] {
@@ -383,7 +436,7 @@
}
{
- TestingContext context;
+ T context;
EXPECT_TRUE(!context.test.source().isActive());
context.test.source().schedule("[Test] BaseCallback",
std::function<bool ()>([&] {
@@ -420,6 +473,27 @@
}
}
+TEST(WTF_GMainLoopSource, DestroyCallbacksAfterReschedulingDuringDispatch)
+{
+ struct TestingContext {
+ GMainLoopSourceTest<GMainLoopSource> test;
+ unsigned firstCallbackCallCount = 0;
+ bool firstDestroyCallbackCalled = false;
+ unsigned secondCallbackCallCount = 0;
+ bool secondDestroyCallbackCalled = false;
+ };
+ destroyCallbacksAfterReschedulingDuringDispatch<TestingContext>();
+
+ struct ThreadSafeTestingContext {
+ GMainLoopSourceTest<GThreadSafeMainLoopSource> test;
+ unsigned firstCallbackCallCount = 0;
+ bool firstDestroyCallbackCalled = false;
+ unsigned secondCallbackCallCount = 0;
+ bool secondDestroyCallbackCalled = false;
+ };
+ destroyCallbacksAfterReschedulingDuringDispatch<ThreadSafeTestingContext>();
+}
+
TEST(WTF_GMainLoopSource, DeleteOnDestroySources)
{
// Testing the delete-on-destroy sources is very limited. There's no good way
@@ -427,7 +501,7 @@
// is destroyed.
struct TestingContext {
- GMainLoopSourceTest test;
+ GMainLoopSourceTest<GMainLoopSource> test;
unsigned callbackCallCount = 0;
bool destroyCallbackCalled = false;
} context;