Title: [176024] trunk
- Revision
- 176024
- Author
- [email protected]
- Date
- 2014-11-12 10:40:45 -0800 (Wed, 12 Nov 2014)
Log Message
[Mac] media/track/audio-track.html is flakey
https://bugs.webkit.org/show_bug.cgi?id=138394
Reviewed by Alexey Proskuryakov.
Source/WebCore:
The above test fails if the HTMLMediaElement's "canplaythrough" event fires before the AudioTrackList's
"addtrack" event fires. This can happen because each object keeps its own GenericEventQueue, which
empties when that individual queue's timer fires. So events can be enqueued in the following order:
1, A, 2, B, 3, C; but fired in a different order: 1, 2, 3, A, B, C.
Make events enqueued in GenericEventQueues globally ordered, so that events are fired in the order
which they are enqueued, regardless of which object owns the queue. Use a static queue of
GenericEventQueues to manage which GenericEventQueue fires and in what order.
GenericEventQueues will use a WeakPtrFactory to cancel pending events. Revoking a GenericEventQueue's
weak pointers means those queue's entries will be skipped the next time the meta-queue is processed.
* dom/GenericEventQueue.cpp:
(WebCore::GenericEventQueue::GenericEventQueue): Create a WeakPtrFactory instead of a Timer.
(WebCore::GenericEventQueue::enqueueEvent): Enqueue this queue with the MetaQueue.
(WebCore::GenericEventQueue::sharedTimer): Lazily-initializing accessor.
(WebCore::GenericEventQueue::sharedTimerFired): Ask each queue to dispatch one event.
(WebCore::GenericEventQueue::pendingQueues): Lazily-initializing accessor.
(WebCore::GenericEventQueue::dispatchOneEvent): Renamed from timerFired.
(WebCore::GenericEventQueue::close): Revoke all WeakPtrs.
(WebCore::GenericEventQueue::cancelAllEvents): Ditto.
(WebCore::GenericEventQueue::hasPendingEvents): Use !isEmpty().
(WebCore::GenericEventQueue::timerFired): Deleted.
* dom/GenericEventQueue.h:
LayoutTests:
* platform/mac/TestExpectations:
Modified Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (176023 => 176024)
--- trunk/LayoutTests/ChangeLog 2014-11-12 18:18:07 UTC (rev 176023)
+++ trunk/LayoutTests/ChangeLog 2014-11-12 18:40:45 UTC (rev 176024)
@@ -1,3 +1,12 @@
+2014-11-12 Jer Noble <[email protected]>
+
+ [Mac] media/track/audio-track.html is flakey
+ https://bugs.webkit.org/show_bug.cgi?id=138394
+
+ Reviewed by Alexey Proskuryakov.
+
+ * platform/mac/TestExpectations:
+
2014-11-12 Alexey Proskuryakov <[email protected]>
Fix a typo in the previous commit - a test should be skipped, not its expectation.
Modified: trunk/LayoutTests/platform/mac/TestExpectations (176023 => 176024)
--- trunk/LayoutTests/platform/mac/TestExpectations 2014-11-12 18:18:07 UTC (rev 176023)
+++ trunk/LayoutTests/platform/mac/TestExpectations 2014-11-12 18:40:45 UTC (rev 176024)
@@ -1504,8 +1504,6 @@
[ Yosemite ] inspector/model/parse-script-syntax-tree.html [ Pass Failure Crash ]
[ Yosemite ] inspector/protocol-promise-result.html [ Pass Failure Crash ]
-webkit.org/b/138394 media/track/audio-track.html [ Pass Failure ]
-
# Specific to Yosemite's font fallback
webkit.org/b/138328 [ Mavericks MountainLion ] platform/mac/fast/text/font-cursive-italic-cjk.html [ Skip ]
Modified: trunk/Source/WebCore/ChangeLog (176023 => 176024)
--- trunk/Source/WebCore/ChangeLog 2014-11-12 18:18:07 UTC (rev 176023)
+++ trunk/Source/WebCore/ChangeLog 2014-11-12 18:40:45 UTC (rev 176024)
@@ -1,3 +1,35 @@
+2014-11-12 Jer Noble <[email protected]>
+
+ [Mac] media/track/audio-track.html is flakey
+ https://bugs.webkit.org/show_bug.cgi?id=138394
+
+ Reviewed by Alexey Proskuryakov.
+
+ The above test fails if the HTMLMediaElement's "canplaythrough" event fires before the AudioTrackList's
+ "addtrack" event fires. This can happen because each object keeps its own GenericEventQueue, which
+ empties when that individual queue's timer fires. So events can be enqueued in the following order:
+ 1, A, 2, B, 3, C; but fired in a different order: 1, 2, 3, A, B, C.
+
+ Make events enqueued in GenericEventQueues globally ordered, so that events are fired in the order
+ which they are enqueued, regardless of which object owns the queue. Use a static queue of
+ GenericEventQueues to manage which GenericEventQueue fires and in what order.
+
+ GenericEventQueues will use a WeakPtrFactory to cancel pending events. Revoking a GenericEventQueue's
+ weak pointers means those queue's entries will be skipped the next time the meta-queue is processed.
+
+ * dom/GenericEventQueue.cpp:
+ (WebCore::GenericEventQueue::GenericEventQueue): Create a WeakPtrFactory instead of a Timer.
+ (WebCore::GenericEventQueue::enqueueEvent): Enqueue this queue with the MetaQueue.
+ (WebCore::GenericEventQueue::sharedTimer): Lazily-initializing accessor.
+ (WebCore::GenericEventQueue::sharedTimerFired): Ask each queue to dispatch one event.
+ (WebCore::GenericEventQueue::pendingQueues): Lazily-initializing accessor.
+ (WebCore::GenericEventQueue::dispatchOneEvent): Renamed from timerFired.
+ (WebCore::GenericEventQueue::close): Revoke all WeakPtrs.
+ (WebCore::GenericEventQueue::cancelAllEvents): Ditto.
+ (WebCore::GenericEventQueue::hasPendingEvents): Use !isEmpty().
+ (WebCore::GenericEventQueue::timerFired): Deleted.
+ * dom/GenericEventQueue.h:
+
2014-11-12 Carlos Garcia Campos <[email protected]>
[GTK] Expose user script messages to GObject DOM bindings
Modified: trunk/Source/WebCore/dom/GenericEventQueue.cpp (176023 => 176024)
--- trunk/Source/WebCore/dom/GenericEventQueue.cpp 2014-11-12 18:18:07 UTC (rev 176023)
+++ trunk/Source/WebCore/dom/GenericEventQueue.cpp 2014-11-12 18:40:45 UTC (rev 176024)
@@ -28,12 +28,15 @@
#include "Event.h"
#include "EventTarget.h"
+#include "Timer.h"
+#include <wtf/MainThread.h>
+#include <wtf/NeverDestroyed.h>
namespace WebCore {
GenericEventQueue::GenericEventQueue(EventTarget& owner)
: m_owner(owner)
- , m_timer(this, &GenericEventQueue::timerFired)
+ , m_weakPtrFactory(this)
, m_isClosed(false)
{
}
@@ -51,45 +54,70 @@
event->setTarget(0);
m_pendingEvents.append(event);
+ pendingQueues().append(m_weakPtrFactory.createWeakPtr());
+ if (!sharedTimer().isActive())
+ sharedTimer().startOneShot(0);
- if (!m_timer.isActive())
- m_timer.startOneShot(0);
-
return true;
}
-void GenericEventQueue::timerFired(Timer&)
+Timer& GenericEventQueue::sharedTimer()
{
- ASSERT(!m_timer.isActive());
- ASSERT(!m_pendingEvents.isEmpty());
+ ASSERT(isMainThread());
+ static NeverDestroyed<Timer> timer(GenericEventQueue::sharedTimerFired);
+ return timer.get();
+}
- Vector<RefPtr<Event>> pendingEvents;
- m_pendingEvents.swap(pendingEvents);
+void GenericEventQueue::sharedTimerFired()
+{
+ ASSERT(!sharedTimer().isActive());
+ ASSERT(!pendingQueues().isEmpty());
- Ref<EventTarget> protect(m_owner);
- for (unsigned i = 0; i < pendingEvents.size(); ++i) {
- EventTarget& target = pendingEvents[i]->target() ? *pendingEvents[i]->target() : m_owner;
- target.dispatchEvent(pendingEvents[i].release());
+ while (!pendingQueues().isEmpty()) {
+ WeakPtr<GenericEventQueue> queue = pendingQueues().takeFirst();
+ if (!queue)
+ continue;
+ queue->dispatchOneEvent();
}
+
+ if (sharedTimer().isActive())
+ sharedTimer().stop();
}
+Deque<WeakPtr<GenericEventQueue>>& GenericEventQueue::pendingQueues()
+{
+ ASSERT(isMainThread());
+ static NeverDestroyed<Deque<WeakPtr<GenericEventQueue>>> queues;
+ return queues.get();
+}
+
+void GenericEventQueue::dispatchOneEvent()
+{
+ ASSERT(!m_pendingEvents.isEmpty());
+
+ Ref<EventTarget> protect(m_owner);
+ RefPtr<Event> event = m_pendingEvents.takeFirst();
+ EventTarget& target = event->target() ? *event->target() : m_owner;
+ target.dispatchEvent(event.release());
+}
+
void GenericEventQueue::close()
{
m_isClosed = true;
- m_timer.stop();
+ m_weakPtrFactory.revokeAll();
m_pendingEvents.clear();
}
void GenericEventQueue::cancelAllEvents()
{
- m_timer.stop();
+ m_weakPtrFactory.revokeAll();
m_pendingEvents.clear();
}
bool GenericEventQueue::hasPendingEvents() const
{
- return m_pendingEvents.size();
+ return !m_pendingEvents.isEmpty();
}
}
Modified: trunk/Source/WebCore/dom/GenericEventQueue.h (176023 => 176024)
--- trunk/Source/WebCore/dom/GenericEventQueue.h 2014-11-12 18:18:07 UTC (rev 176023)
+++ trunk/Source/WebCore/dom/GenericEventQueue.h 2014-11-12 18:40:45 UTC (rev 176024)
@@ -26,15 +26,16 @@
#ifndef GenericEventQueue_h
#define GenericEventQueue_h
-#include "Timer.h"
+#include <wtf/Deque.h>
#include <wtf/Forward.h>
#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
+#include <wtf/WeakPtr.h>
namespace WebCore {
class Event;
class EventTarget;
+class Timer;
class GenericEventQueue {
public:
@@ -48,11 +49,15 @@
bool hasPendingEvents() const;
private:
- void timerFired(Timer&);
+ static Timer& sharedTimer();
+ static void sharedTimerFired();
+ static Deque<WeakPtr<GenericEventQueue>>& pendingQueues();
+ void dispatchOneEvent();
+
EventTarget& m_owner;
- Vector<RefPtr<Event>> m_pendingEvents;
- Timer m_timer;
+ Deque<RefPtr<Event>> m_pendingEvents;
+ WeakPtrFactory<GenericEventQueue> m_weakPtrFactory;
bool m_isClosed;
};
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes