Unreviewed, rolling out r200627.
authorryanhaddad@apple.com <ryanhaddad@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 May 2016 20:21:45 +0000 (20:21 +0000)
committerryanhaddad@apple.com <ryanhaddad@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 May 2016 20:21:45 +0000 (20:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=157531

This change has caused crashes in existing LayoutTests
(Requested by ryanhaddad on #webkit).

Reverted changeset:

"Return a Promise from HTMLMediaElement.play()"
https://bugs.webkit.org/show_bug.cgi?id=157400
http://trac.webkit.org/changeset/200627

Patch by Commit Queue <commit-queue@webkit.org> on 2016-05-10

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@200637 268f45cc-cd09-0410-ab3c-d52691b4dbfc

27 files changed:
LayoutTests/ChangeLog
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/html/dom/interfaces-expected.txt
LayoutTests/media/media-play-promise-reject-error-notsupported-expected.txt [deleted file]
LayoutTests/media/media-play-promise-reject-error-notsupported.html [deleted file]
LayoutTests/media/media-play-promise-reject-load-abort-expected.txt [deleted file]
LayoutTests/media/media-play-promise-reject-load-abort.html [deleted file]
LayoutTests/media/media-play-promise-reject-pause-abort-expected.txt [deleted file]
LayoutTests/media/media-play-promise-reject-pause-abort.html [deleted file]
LayoutTests/media/media-play-promise-reject-play-notallowed-expected.txt [deleted file]
LayoutTests/media/media-play-promise-reject-play-notallowed.html [deleted file]
LayoutTests/media/media-play-promise-reject-play-notsupported-expected.txt [deleted file]
LayoutTests/media/media-play-promise-reject-play-notsupported.html [deleted file]
LayoutTests/media/media-play-promise-resolve-expected.txt [deleted file]
LayoutTests/media/media-play-promise-resolve-when-playing-expected.txt [deleted file]
LayoutTests/media/media-play-promise-resolve-when-playing.html [deleted file]
LayoutTests/media/media-play-promise-resolve.html [deleted file]
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/GenericEventQueue.cpp
Source/WebCore/dom/GenericEventQueue.h
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/HTMLMediaElement.idl
Source/WebCore/platform/GenericTaskQueue.cpp [deleted file]
Source/WebCore/platform/GenericTaskQueue.h

index 94b0620..8dfe7af 100644 (file)
@@ -1,3 +1,17 @@
+2016-05-10  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r200627.
+        https://bugs.webkit.org/show_bug.cgi?id=157531
+
+        This change has caused crashes in existing LayoutTests
+        (Requested by ryanhaddad on #webkit).
+
+        Reverted changeset:
+
+        "Return a Promise from HTMLMediaElement.play()"
+        https://bugs.webkit.org/show_bug.cgi?id=157400
+        http://trac.webkit.org/changeset/200627
+
 2016-05-10  Simon Fraser  <simon.fraser@apple.com>
 
         Fix scrolling tree dumping
index 80a5b36..a0b71aa 100644 (file)
@@ -1,3 +1,17 @@
+2016-05-10  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r200627.
+        https://bugs.webkit.org/show_bug.cgi?id=157531
+
+        This change has caused crashes in existing LayoutTests
+        (Requested by ryanhaddad on #webkit).
+
+        Reverted changeset:
+
+        "Return a Promise from HTMLMediaElement.play()"
+        https://bugs.webkit.org/show_bug.cgi?id=157400
+        http://trac.webkit.org/changeset/200627
+
 2016-05-06  Jer Noble  <jer.noble@apple.com>
 
         Return a Promise from HTMLMediaElement.play()
index f9e64eb..88d8485 100644 (file)
@@ -2447,9 +2447,7 @@ PASS HTMLMediaElement interface: attribute seekable
 PASS HTMLMediaElement interface: attribute ended 
 PASS HTMLMediaElement interface: attribute autoplay 
 PASS HTMLMediaElement interface: attribute loop 
-FAIL HTMLMediaElement interface: operation play() assert_throws: calling operation with this = null didn't throw TypeError function "function () {
-            fn.apply(obj, args);
-        }" did not throw
+PASS HTMLMediaElement interface: operation play() 
 PASS HTMLMediaElement interface: operation pause() 
 PASS HTMLMediaElement interface: attribute mediaGroup 
 PASS HTMLMediaElement interface: attribute controller 
diff --git a/LayoutTests/media/media-play-promise-reject-error-notsupported-expected.txt b/LayoutTests/media/media-play-promise-reject-error-notsupported-expected.txt
deleted file mode 100644 (file)
index def321c..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-
-RUN(mediaElement.src = findMediaFile("video", "content/invalid"))
-RUN(mediaElement.play().then(failTest).catch(promiseRejected))
-Promise rejected. OK
-EXPECTED (error.name == 'NotSupportedError') OK
-END OF TEST
-
diff --git a/LayoutTests/media/media-play-promise-reject-error-notsupported.html b/LayoutTests/media/media-play-promise-reject-error-notsupported.html
deleted file mode 100644 (file)
index 42d77aa..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <script src=media-file.js></script>
-        <script src=video-test.js></script>
-
-        <script>
-        var promise;
-        var error;
-        function start()
-        {
-            findMediaElement();
-            run('mediaElement.src = findMediaFile("video", "content/invalid")');
-            run('mediaElement.play().then(failTest).catch(promiseRejected)');    
-        }
-        function promiseRejected(e)
-        {
-            error = e;
-            logResult(true, "Promise rejected.");
-            testExpected('error.name', 'NotSupportedError');
-            endTest();
-        }
-        </script>
-    </head>
-
-    <body onload="start()">
-
-        <video></video>
-    
-    </body>
-</html>
diff --git a/LayoutTests/media/media-play-promise-reject-load-abort-expected.txt b/LayoutTests/media/media-play-promise-reject-load-abort-expected.txt
deleted file mode 100644 (file)
index f618897..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-
-RUN(mediaElement.play().then(failTest).catch(promiseRejected))
-RUN(mediaElement.src = findMediaFile("video", "content/test"))
-Promise rejected. OK
-EXPECTED (error.name == 'AbortError') OK
-END OF TEST
-
diff --git a/LayoutTests/media/media-play-promise-reject-load-abort.html b/LayoutTests/media/media-play-promise-reject-load-abort.html
deleted file mode 100644 (file)
index 5cb2faf..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <script src=media-file.js></script>
-        <script src=video-test.js></script>
-
-        <script>
-        var promise;
-        var error;
-        function start()
-        {
-            findMediaElement();
-            run('mediaElement.play().then(failTest).catch(promiseRejected)');    
-            run('mediaElement.src = findMediaFile("video", "content/test")');
-        }
-        function promiseRejected(e)
-        {
-            error = e;
-            logResult(true, "Promise rejected.");
-            testExpected('error.name', 'AbortError');
-            endTest();
-        }
-        </script>
-    </head>
-
-    <body onload="start()">
-
-        <video></video>
-    
-    </body>
-</html>
diff --git a/LayoutTests/media/media-play-promise-reject-pause-abort-expected.txt b/LayoutTests/media/media-play-promise-reject-pause-abort-expected.txt
deleted file mode 100644 (file)
index 6a8ef34..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-
-RUN(mediaElement.play().then(failTest).catch(promiseRejected))
-RUN(mediaElement.pause())
-Promise rejected. OK
-EXPECTED (error.name == 'AbortError') OK
-END OF TEST
-
diff --git a/LayoutTests/media/media-play-promise-reject-pause-abort.html b/LayoutTests/media/media-play-promise-reject-pause-abort.html
deleted file mode 100644 (file)
index 44431ed..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <script src=media-file.js></script>
-        <script src=video-test.js></script>
-
-        <script>
-        var promise;
-        var error;
-        function start()
-        {
-            findMediaElement();
-            run('mediaElement.play().then(failTest).catch(promiseRejected)');    
-            run('mediaElement.pause()');
-        }
-        function promiseRejected(e)
-        {
-            error = e;
-            logResult(true, "Promise rejected.");
-            testExpected('error.name', 'AbortError');
-            endTest();
-        }
-        </script>
-    </head>
-
-    <body onload="start()">
-
-        <video></video>
-    
-    </body>
-</html>
diff --git a/LayoutTests/media/media-play-promise-reject-play-notallowed-expected.txt b/LayoutTests/media/media-play-promise-reject-play-notallowed-expected.txt
deleted file mode 100644 (file)
index 14d89cc..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-RUN(internals.setMediaElementRestrictions(mediaElement, "RequireUserGestureForVideoRateChange"))
-RUN(mediaElement.src = findMediaFile("video", "content/test"))
-RUN(mediaElement.play().then(failTest).catch(promiseRejected))
-Promise rejected. OK
-EXPECTED (error.name == 'NotAllowedError') OK
-END OF TEST
-
diff --git a/LayoutTests/media/media-play-promise-reject-play-notallowed.html b/LayoutTests/media/media-play-promise-reject-play-notallowed.html
deleted file mode 100644 (file)
index f789e92..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <script src=media-file.js></script>
-        <script src=video-test.js></script>
-
-        <script>
-        var promise;
-        var error;
-        function start()
-        {
-            findMediaElement();
-               if (window.internals)
-                   run('internals.setMediaElementRestrictions(mediaElement, "RequireUserGestureForVideoRateChange")');
-
-            run('mediaElement.src = findMediaFile("video", "content/test")');
-            run('mediaElement.play().then(failTest).catch(promiseRejected)');    
-        }
-
-        function promiseRejected(e)
-        {
-            error = e;
-            logResult(true, "Promise rejected.");
-            testExpected('error.name', 'NotAllowedError');
-            endTest();
-        }
-        </script>
-    </head>
-
-    <body onload="start()">
-
-        <video></video>
-    
-    </body>
-</html>
diff --git a/LayoutTests/media/media-play-promise-reject-play-notsupported-expected.txt b/LayoutTests/media/media-play-promise-reject-play-notsupported-expected.txt
deleted file mode 100644 (file)
index a6f8199..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-RUN(mediaElement.src = findMediaFile("video", "content/invalid"))
-EVENT(error)
-RUN(mediaElement.play().then(failTest).catch(promiseRejected))
-Promise rejected. OK
-EXPECTED (error.name == 'NotSupportedError') OK
-END OF TEST
-
diff --git a/LayoutTests/media/media-play-promise-reject-play-notsupported.html b/LayoutTests/media/media-play-promise-reject-play-notsupported.html
deleted file mode 100644 (file)
index 413f303..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <script src=media-file.js></script>
-        <script src=video-test.js></script>
-
-        <script>
-        var promise;
-        var error;
-        function start()
-        {
-            findMediaElement();
-            run('mediaElement.src = findMediaFile("video", "content/invalid")');
-            waitForEventOnce('error', error);
-        }
-
-        function error()
-        {
-            run('mediaElement.play().then(failTest).catch(promiseRejected)');    
-        }
-
-        function promiseRejected(e)
-        {
-            error = e;
-            logResult(true, "Promise rejected.");
-            testExpected('error.name', 'NotSupportedError');
-            endTest();
-        }
-        </script>
-    </head>
-
-    <body onload="start()">
-
-        <video></video>
-    
-    </body>
-</html>
diff --git a/LayoutTests/media/media-play-promise-resolve-expected.txt b/LayoutTests/media/media-play-promise-resolve-expected.txt
deleted file mode 100644 (file)
index 0063eed..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-
-RUN(mediaElement.src = findMediaFile("video", "content/test"))
-RUN(mediaElement.play().then(promiseResolved).catch(failTest))
-Promise resolved. OK
-END OF TEST
-
diff --git a/LayoutTests/media/media-play-promise-resolve-when-playing-expected.txt b/LayoutTests/media/media-play-promise-resolve-when-playing-expected.txt
deleted file mode 100644 (file)
index 1659a1f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-RUN(mediaElement.src = findMediaFile("video", "content/test"))
-RUN(mediaElement.play())
-EVENT(playing)
-RUN(mediaElement.play().then(promiseResolved).catch(failTest))
-Promise resolved. OK
-END OF TEST
-
diff --git a/LayoutTests/media/media-play-promise-resolve-when-playing.html b/LayoutTests/media/media-play-promise-resolve-when-playing.html
deleted file mode 100644 (file)
index d1d4efa..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <script src=media-file.js></script>
-        <script src=video-test.js></script>
-
-        <script>
-        var promise;
-        function start()
-        {
-            findMediaElement();
-            run('mediaElement.src = findMediaFile("video", "content/test")');
-            run('mediaElement.play()');
-            waitForEventOnce('playing', playing);
-        }
-
-        function playing()
-        {
-            run('mediaElement.play().then(promiseResolved).catch(failTest)');    
-        }
-
-        function promiseResolved()
-        {
-            logResult(true, "Promise resolved.");
-            endTest();
-        }
-        </script>
-    </head>
-
-    <body onload="start()">
-
-        <video></video>
-    
-    </body>
-</html>
diff --git a/LayoutTests/media/media-play-promise-resolve.html b/LayoutTests/media/media-play-promise-resolve.html
deleted file mode 100644 (file)
index 58a3278..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <script src=media-file.js></script>
-        <script src=video-test.js></script>
-
-        <script>
-        var promise;
-        function start()
-        {
-            findMediaElement();
-            run('mediaElement.src = findMediaFile("video", "content/test")');
-            run('mediaElement.play().then(promiseResolved).catch(failTest)');
-        }
-
-        function promiseResolved()
-        {
-            logResult(true, "Promise resolved.");
-            endTest();
-        }
-        </script>
-    </head>
-
-    <body onload="start()">
-
-        <video></video>
-    
-    </body>
-</html>
index 7550b00..a984ae0 100644 (file)
@@ -2109,7 +2109,6 @@ set(WebCore_SOURCES
     platform/FileChooser.cpp
     platform/FileStream.cpp
     platform/FileSystem.cpp
-    platform/GenericTaskQueue.cpp
     platform/Language.cpp
     platform/Length.cpp
     platform/LengthBox.cpp
index d7d0f67..46d5c99 100644 (file)
@@ -1,3 +1,17 @@
+2016-05-10  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r200627.
+        https://bugs.webkit.org/show_bug.cgi?id=157531
+
+        This change has caused crashes in existing LayoutTests
+        (Requested by ryanhaddad on #webkit).
+
+        Reverted changeset:
+
+        "Return a Promise from HTMLMediaElement.play()"
+        https://bugs.webkit.org/show_bug.cgi?id=157400
+        http://trac.webkit.org/changeset/200627
+
 2016-05-10  Simon Fraser  <simon.fraser@apple.com>
 
         Fix scrolling tree dumping
index f526727..7ac102e 100644 (file)
                CD3E252318046BCD00E27F56 /* CSSGridTemplateAreasValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD3E252118046BCD00E27F56 /* CSSGridTemplateAreasValue.cpp */; };
                CD3E252418046BCD00E27F56 /* CSSGridTemplateAreasValue.h in Headers */ = {isa = PBXBuildFile; fileRef = CD3E252218046BCD00E27F56 /* CSSGridTemplateAreasValue.h */; };
                CD4AC52A1496AE9A0087C4EF /* Composite.wav in Copy Audio Resources */ = {isa = PBXBuildFile; fileRef = CD4AC5281496AE2F0087C4EF /* Composite.wav */; };
-               CD4BE52A1CE136EF009D87DA /* GenericTaskQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD4BE5291CE13425009D87DA /* GenericTaskQueue.cpp */; };
                CD5209E41B0BD8380077184E /* MediaPlayerEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5209E31B0BD8380077184E /* MediaPlayerEnums.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CD5209E61B0BD9E10077184E /* HTMLMediaElementEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5209E51B0BD9E10077184E /* HTMLMediaElementEnums.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CD52481A18E200ED0008A07D /* DisplaySleepDisabler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD52481818E200ED0008A07D /* DisplaySleepDisabler.cpp */; };
                CD3E252218046BCD00E27F56 /* CSSGridTemplateAreasValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSGridTemplateAreasValue.h; sourceTree = "<group>"; };
                CD4097FF1A8C855F004C65E9 /* CFNSURLConnectionSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFNSURLConnectionSPI.h; sourceTree = "<group>"; };
                CD4AC5281496AE2F0087C4EF /* Composite.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = Composite.wav; path = platform/audio/resources/Composite.wav; sourceTree = SOURCE_ROOT; };
-               CD4BE5291CE13425009D87DA /* GenericTaskQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GenericTaskQueue.cpp; sourceTree = "<group>"; };
                CD4E0AFA11F7BC27009D3811 /* fullscreen.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = fullscreen.css; sourceTree = "<group>"; };
                CD5209E31B0BD8380077184E /* MediaPlayerEnums.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlayerEnums.h; sourceTree = "<group>"; };
                CD5209E51B0BD9E10077184E /* HTMLMediaElementEnums.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLMediaElementEnums.h; sourceTree = "<group>"; };
                                5179CE23195C81420019C198 /* GamepadProvider.h */,
                                5179CE29195C91860019C198 /* GamepadProviderClient.h */,
                                CD62FB941AF018E70012ED7D /* GenericTaskQueue.h */,
-                               CD4BE5291CE13425009D87DA /* GenericTaskQueue.cpp */,
                                A8748BDF12CBF2DC001FBA41 /* HashTools.h */,
                                BC3BC29B0E91AB0F00835588 /* HostWindow.h */,
                                862F129F18C1DCE4005C54AF /* HysteresisActivity.h */,
                                D70AD65713E1342B005B50B4 /* RenderRegion.cpp in Sources */,
                                BCE93F471517C6D5008CCF74 /* RenderRegionSet.cpp in Sources */,
                                A871DFE20A15376B00B12A68 /* RenderReplaced.cpp in Sources */,
-                               CD4BE52A1CE136EF009D87DA /* GenericTaskQueue.cpp in Sources */,
                                BCA846D60DC67A350026C309 /* RenderReplica.cpp in Sources */,
                                1479FAED109AE37500DED655 /* RenderRuby.cpp in Sources */,
                                1479FAEF109AE37500DED655 /* RenderRubyBase.cpp in Sources */,
index feb4c21..694c493 100644 (file)
@@ -28,7 +28,6 @@
 
 #include "Event.h"
 #include "EventTarget.h"
-#include "ScriptExecutionContext.h"
 #include "Timer.h"
 #include <wtf/MainThread.h>
 #include <wtf/NeverDestroyed.h>
@@ -37,6 +36,7 @@ namespace WebCore {
 
 GenericEventQueue::GenericEventQueue(EventTarget& owner)
     : m_owner(owner)
+    , m_weakPtrFactory(this)
     , m_isClosed(false)
 {
 }
@@ -58,7 +58,40 @@ void GenericEventQueue::enqueueEvent(RefPtr<Event>&& event)
     if (m_isSuspended)
         return;
 
-    m_taskQueue.enqueueTask(std::bind(&GenericEventQueue::dispatchOneEvent, this));
+    pendingQueues().append(m_weakPtrFactory.createWeakPtr());
+    if (!sharedTimer().isActive())
+        sharedTimer().startOneShot(0);
+}
+
+Timer& GenericEventQueue::sharedTimer()
+{
+    ASSERT(isMainThread());
+    static NeverDestroyed<Timer> timer(GenericEventQueue::sharedTimerFired);
+    return timer.get();
+}
+
+void GenericEventQueue::sharedTimerFired()
+{
+    ASSERT(!sharedTimer().isActive());
+    ASSERT(!pendingQueues().isEmpty());
+
+    // Copy the pending events first because we don't want to process synchronously the new events
+    // queued by the JS events handlers that are executed in the loop below.
+    Deque<WeakPtr<GenericEventQueue>> queuedEvents;
+    std::swap(queuedEvents, pendingQueues());
+    while (!queuedEvents.isEmpty()) {
+        WeakPtr<GenericEventQueue> queue = queuedEvents.takeFirst();
+        if (!queue)
+            continue;
+        queue->dispatchOneEvent();
+    }
+}
+
+Deque<WeakPtr<GenericEventQueue>>& GenericEventQueue::pendingQueues()
+{
+    ASSERT(isMainThread());
+    static NeverDestroyed<Deque<WeakPtr<GenericEventQueue>>> queues;
+    return queues.get();
 }
 
 void GenericEventQueue::dispatchOneEvent()
@@ -75,13 +108,13 @@ void GenericEventQueue::close()
 {
     m_isClosed = true;
 
-    m_taskQueue.close();
+    m_weakPtrFactory.revokeAll();
     m_pendingEvents.clear();
 }
 
 void GenericEventQueue::cancelAllEvents()
 {
-    m_taskQueue.cancelAllTasks();
+    m_weakPtrFactory.revokeAll();
     m_pendingEvents.clear();
 }
 
@@ -94,7 +127,7 @@ void GenericEventQueue::suspend()
 {
     ASSERT(!m_isSuspended);
     m_isSuspended = true;
-    m_taskQueue.cancelAllTasks();
+    m_weakPtrFactory.revokeAll();
 }
 
 void GenericEventQueue::resume()
@@ -108,7 +141,10 @@ void GenericEventQueue::resume()
         return;
 
     for (unsigned i = 0; i < m_pendingEvents.size(); ++i)
-        m_taskQueue.enqueueTask(std::bind(&GenericEventQueue::dispatchOneEvent, this));
+        pendingQueues().append(m_weakPtrFactory.createWeakPtr());
+
+    if (!sharedTimer().isActive())
+        sharedTimer().startOneShot(0);
 }
 
 }
index b111b01..d3a038a 100644 (file)
@@ -26,7 +26,6 @@
 #ifndef GenericEventQueue_h
 #define GenericEventQueue_h
 
-#include "GenericTaskQueue.h"
 #include <wtf/Deque.h>
 #include <wtf/Forward.h>
 #include <wtf/RefPtr.h>
@@ -53,11 +52,15 @@ public:
     void resume();
 
 private:
+    static Timer& sharedTimer();
+    static void sharedTimerFired();
+    static Deque<WeakPtr<GenericEventQueue>>& pendingQueues();
+
     void dispatchOneEvent();
 
     EventTarget& m_owner;
-    GenericTaskQueue<Timer> m_taskQueue;
     Deque<RefPtr<Event>> m_pendingEvents;
+    WeakPtrFactory<GenericEventQueue> m_weakPtrFactory;
     bool m_isClosed;
     bool m_isSuspended { false };
 };
index b883f67..300cf6a 100644 (file)
@@ -51,7 +51,6 @@
 #include "FrameView.h"
 #include "HTMLSourceElement.h"
 #include "HTMLVideoElement.h"
-#include "JSDOMError.h"
 #include "JSHTMLMediaElement.h"
 #include "Language.h"
 #include "Logging.h"
@@ -349,6 +348,10 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
     , m_progressEventTimer(*this, &HTMLMediaElement::progressEventTimerFired)
     , m_playbackProgressTimer(*this, &HTMLMediaElement::playbackProgressTimerFired)
     , m_scanTimer(*this, &HTMLMediaElement::scanTimerFired)
+    , m_pauseAfterDetachedTimer(*this, &HTMLMediaElement::pauseAfterDetachedTimerFired)
+    , m_seekTaskQueue(document)
+    , m_resizeTaskQueue(document)
+    , m_shadowDOMTaskQueue(document)
     , m_playedTimeRanges()
     , m_asyncEventQueue(*this)
     , m_requestedPlaybackRate(1)
@@ -557,8 +560,6 @@ HTMLMediaElement::~HTMLMediaElement()
 #endif
 
     m_seekTaskQueue.close();
-    m_promiseTaskQueue.close();
-    m_pauseAfterDetachedTaskQueue.close();
 
     m_completelyLoaded = true;
 }
@@ -778,7 +779,7 @@ Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode&
     return InsertionDone;
 }
 
-void HTMLMediaElement::pauseAfterDetachedTask()
+void HTMLMediaElement::pauseAfterDetachedTimerFired()
 {
     // If we were re-inserted into an active document, no need to pause.
     if (m_inActiveDocument)
@@ -814,7 +815,7 @@ void HTMLMediaElement::removedFrom(ContainerNode& insertionPoint)
     m_inActiveDocument = false;
     if (insertionPoint.inDocument()) {
         // Pause asynchronously to let the operation that removed us finish, in case we get inserted back into a document.
-        m_pauseAfterDetachedTaskQueue.enqueueTask(std::bind(&HTMLMediaElement::pauseAfterDetachedTask, this));
+        m_pauseAfterDetachedTimer.startOneShot(0);
     }
 
     HTMLElement::removedFrom(insertionPoint);
@@ -902,38 +903,6 @@ void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
     m_asyncEventQueue.enqueueEvent(WTFMove(event));
 }
 
-void HTMLMediaElement::scheduleResolvePendingPlayPromises()
-{
-    m_promiseTaskQueue.enqueueTask(std::bind(&HTMLMediaElement::resolvePendingPlayPromises, this));
-}
-
-void HTMLMediaElement::rejectPendingPlayPromises(DOMError& error)
-{
-    Vector<PlayPromise> pendingPlayPromises = WTFMove(m_pendingPlayPromises);
-
-    for (auto& promise : pendingPlayPromises)
-        promise.reject(error);
-}
-
-void HTMLMediaElement::resolvePendingPlayPromises()
-{
-    Vector<PlayPromise> pendingPlayPromises = WTFMove(m_pendingPlayPromises);
-
-    for (auto& promise : pendingPlayPromises)
-        promise.resolve(nullptr);
-}
-
-void HTMLMediaElement::scheduleNotifyAboutPlaying()
-{
-    m_promiseTaskQueue.enqueueTask(std::bind(&HTMLMediaElement::notifyAboutPlaying, this));
-}
-
-void HTMLMediaElement::notifyAboutPlaying()
-{
-    dispatchEvent(Event::create(eventNames().playingEvent, false, true));
-    resolvePendingPlayPromises();
-}
-
 void HTMLMediaElement::pendingActionTimerFired()
 {
     Ref<HTMLMediaElement> protect(*this); // loadNextSourceChild may fire 'beforeload', which can make arbitrary DOM mutations.
@@ -1946,8 +1915,6 @@ void HTMLMediaElement::noneSupported()
     // 7 - Queue a task to fire a simple event named error at the media element.
     scheduleEvent(eventNames().errorEvent);
 
-    rejectPendingPlayPromises(DOMError::create("NotSupportedError", "The operation is not supported."));
-
 #if ENABLE(MEDIA_SOURCE)
     closeMediaSource();
 #endif
@@ -2012,8 +1979,6 @@ void HTMLMediaElement::cancelPendingEventsAndCallbacks()
 
     for (auto& source : childrenOfType<HTMLSourceElement>(*this))
         source.cancelPendingErrorEvent();
-
-    rejectPendingPlayPromises(DOMError::create("AbortError", "The operation was aborted."));
 }
 
 void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
@@ -2277,7 +2242,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
     if (m_readyState == HAVE_FUTURE_DATA && oldState <= HAVE_CURRENT_DATA && tracksAreReady) {
         scheduleEvent(eventNames().canplayEvent);
         if (isPotentiallyPlaying)
-            scheduleNotifyAboutPlaying();
+            scheduleEvent(eventNames().playingEvent);
         shouldUpdateDisplayState = true;
     }
 
@@ -2288,13 +2253,13 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
         scheduleEvent(eventNames().canplaythroughEvent);
 
         if (isPotentiallyPlaying && oldState <= HAVE_CURRENT_DATA)
-            scheduleNotifyAboutPlaying();
+            scheduleEvent(eventNames().playingEvent);
 
         if (canTransitionFromAutoplayToPlay()) {
             m_paused = false;
             invalidateCachedTime();
             scheduleEvent(eventNames().playEvent);
-            scheduleNotifyAboutPlaying();
+            scheduleEvent(eventNames().playingEvent);
         }
 
         shouldUpdateDisplayState = true;
@@ -3021,29 +2986,6 @@ void HTMLMediaElement::setPreload(const String& preload)
     setAttribute(preloadAttr, preload);
 }
 
-void HTMLMediaElement::play(PlayPromise&& promise)
-{
-    LOG(Media, "HTMLMediaElement::play(%p)", this);
-
-    if (!m_mediaSession->playbackPermitted(*this)) {
-        promise.reject(DOMError::create("NotAllowedError", "The request is not allowed by the user agent or the platform in the current context."));
-        return;
-    }
-
-    if (m_error && m_error->code() == MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED) {
-        promise.reject(DOMError::create("NotSupportedError", "The operation is not supported.."));
-        return;
-    }
-
-    if (ScriptController::processingUserGestureForMedia())
-        removeBehaviorsRestrictionsAfterFirstUserGesture();
-
-    if (!playInternal())
-        promise.reject(DOMError::create("NotAllowedError", "The request is not allowed by the user agent or the platform in the current context."));
-
-    m_pendingPlayPromises.append(WTFMove(promise));
-}
-
 void HTMLMediaElement::play()
 {
     LOG(Media, "HTMLMediaElement::play(%p)", this);
@@ -3056,13 +2998,13 @@ void HTMLMediaElement::play()
     playInternal();
 }
 
-bool HTMLMediaElement::playInternal()
+void HTMLMediaElement::playInternal()
 {
     LOG(Media, "HTMLMediaElement::playInternal(%p)", this);
     
     if (!m_mediaSession->clientWillBeginPlayback()) {
         LOG(Media, "  returning because of interruption");
-        return false;
+        return;
     }
 
     // 4.8.10.9. Playing the media resource
@@ -3083,7 +3025,7 @@ bool HTMLMediaElement::playInternal()
         if (m_readyState <= HAVE_CURRENT_DATA)
             scheduleEvent(eventNames().waitingEvent);
         else if (m_readyState >= HAVE_FUTURE_DATA)
-            scheduleNotifyAboutPlaying();
+            scheduleEvent(eventNames().playingEvent);
 
 #if ENABLE(MEDIA_SESSION)
         // 6.3 Activating a media session from a media element
@@ -3105,18 +3047,15 @@ bool HTMLMediaElement::playInternal()
 
                 if (!m_session->invoke()) {
                     pause();
-                    return false;
+                    return;
                 }
             }
         }
 #endif
-    } else if (m_readyState >= HAVE_FUTURE_DATA)
-        scheduleResolvePendingPlayPromises();
-
+    }
     m_autoplaying = false;
     updatePlayState();
     updateMediaController();
-    return true;
 }
 
 void HTMLMediaElement::pause()
@@ -3154,7 +3093,6 @@ void HTMLMediaElement::pauseInternal()
         m_paused = true;
         scheduleTimeupdateEvent(false);
         scheduleEvent(eventNames().pauseEvent);
-        rejectPendingPlayPromises(DOMError::create("AbortError", "The operation was aborted."));
 
         if (MemoryPressureHandler::singleton().isUnderMemoryPressure())
             purgeBufferedDataIfPossible();
@@ -5067,8 +5005,6 @@ void HTMLMediaElement::contextDestroyed()
     m_seekTaskQueue.close();
     m_resizeTaskQueue.close();
     m_shadowDOMTaskQueue.close();
-    m_promiseTaskQueue.close();
-    m_pauseAfterDetachedTaskQueue.close();
 
     ActiveDOMObject::contextDestroyed();
 }
@@ -5080,7 +5016,6 @@ void HTMLMediaElement::stop()
     stopWithoutDestroyingMediaPlayer();
 
     m_asyncEventQueue.close();
-    m_promiseTaskQueue.close();
 
     // Once an active DOM object has been stopped it can not be restarted, so we can deallocate
     // the media player now. Note that userCancelledLoad will already called clearMediaPlayer
index d8bc155..76a793d 100644 (file)
@@ -32,7 +32,6 @@
 #include "GenericEventQueue.h"
 #include "GenericTaskQueue.h"
 #include "HTMLMediaElementEnums.h"
-#include "JSDOMPromise.h"
 #include "MediaCanStartListener.h"
 #include "MediaControllerInterface.h"
 #include "MediaElementSession.h"
@@ -59,7 +58,6 @@ namespace WebCore {
 class AudioSourceProvider;
 class MediaElementAudioSourceNode;
 #endif
-class DOMError;
 class DisplaySleepDisabler;
 class Event;
 class HTMLSourceElement;
@@ -143,11 +141,6 @@ public:
 
     using HTMLMediaElementEnums::DelayedActionType;
     void scheduleDelayedAction(DelayedActionType);
-    void scheduleResolvePendingPlayPromises();
-    void rejectPendingPlayPromises(DOMError&);
-    void resolvePendingPlayPromises();
-    void scheduleNotifyAboutPlaying();
-    void notifyAboutPlaying();
     
     MediaPlayerEnums::MovieLoadType movieLoadType() const;
     
@@ -211,10 +204,6 @@ public:
     bool isAutoplaying() const { return m_autoplaying; }
     bool loop() const;
     void setLoop(bool b);
-
-    typedef DOMPromise<std::nullptr_t, DOMError&> PlayPromise;
-    void play(PlayPromise&&);
-
     WEBCORE_EXPORT void play() override;
     WEBCORE_EXPORT void pause() override;
     void setShouldBufferData(bool) override;
@@ -682,7 +671,7 @@ private:
 
     // These "internal" functions do not check user gesture restrictions.
     void loadInternal();
-    bool playInternal();
+    void playInternal();
     void pauseInternal();
 
     void prepareForLoad();
@@ -783,22 +772,19 @@ private:
     void isVisibleInViewportChanged() final;
     void updateShouldAutoplay();
 
-    void pauseAfterDetachedTask();
+    void pauseAfterDetachedTimerFired();
 
     Timer m_pendingActionTimer;
     Timer m_progressEventTimer;
     Timer m_playbackProgressTimer;
     Timer m_scanTimer;
-    GenericTaskQueue<Timer> m_seekTaskQueue;
-    GenericTaskQueue<Timer> m_resizeTaskQueue;
-    GenericTaskQueue<Timer> m_shadowDOMTaskQueue;
-    GenericTaskQueue<Timer> m_promiseTaskQueue;
-    GenericTaskQueue<Timer> m_pauseAfterDetachedTaskQueue;
+    Timer m_pauseAfterDetachedTimer;
+    GenericTaskQueue<ScriptExecutionContext> m_seekTaskQueue;
+    GenericTaskQueue<ScriptExecutionContext> m_resizeTaskQueue;
+    GenericTaskQueue<ScriptExecutionContext> m_shadowDOMTaskQueue;
     RefPtr<TimeRanges> m_playedTimeRanges;
     GenericEventQueue m_asyncEventQueue;
 
-    Vector<PlayPromise> m_pendingPlayPromises;
-
     double m_requestedPlaybackRate;
     double m_reportedPlaybackRate;
     double m_defaultPlaybackRate;
index d04ad11..9766e7f 100644 (file)
@@ -75,7 +75,7 @@
     readonly attribute boolean ended;
     [Reflect] attribute boolean autoplay;
     [Reflect] attribute boolean loop;
-    Promise play();
+    void play();
     void pause();
     void fastSeek(unrestricted double time);
 
diff --git a/Source/WebCore/platform/GenericTaskQueue.cpp b/Source/WebCore/platform/GenericTaskQueue.cpp
deleted file mode 100644 (file)
index 5f2576a..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- * 
- * 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 "GenericTaskQueue.h"
-
-#include <wtf/MainThread.h>
-#include <wtf/NeverDestroyed.h>
-
-namespace WebCore {
-
-TaskDispatcher<Timer>::~TaskDispatcher()
-{
-    Deque<TaskDispatcher<Timer>*> replacementQueue;
-    for (auto* dispatcher : pendingDispatchers()) {
-        if (dispatcher != this)
-            replacementQueue.append(dispatcher);
-    }
-    if (replacementQueue.isEmpty())
-        sharedTimer().stop();
-    pendingDispatchers() = WTFMove(replacementQueue);
-}
-
-void TaskDispatcher<Timer>::postTask(std::function<void()> function)
-{
-    m_pendingTasks.append(WTFMove(function));
-    pendingDispatchers().append(this);
-    if (!sharedTimer().isActive())
-        sharedTimer().startOneShot(0);
-}
-
-Timer& TaskDispatcher<Timer>::sharedTimer()
-{
-    ASSERT(isMainThread());
-    static NeverDestroyed<Timer> timer(TaskDispatcher<Timer>::sharedTimerFired);
-    return timer.get();
-}
-
-void TaskDispatcher<Timer>::sharedTimerFired()
-{
-    ASSERT(!sharedTimer().isActive());
-    ASSERT(!pendingDispatchers().isEmpty());
-
-    // Copy the pending events first because we don't want to process synchronously the new events
-    // queued by the JS events handlers that are executed in the loop below.
-    Deque<TaskDispatcher<Timer>*> queuedDispatchers = WTFMove(pendingDispatchers());
-    while (!queuedDispatchers.isEmpty()) {
-        TaskDispatcher<Timer>* dispatcher = queuedDispatchers.takeFirst();
-        if (!dispatcher)
-            continue;
-        dispatcher->dispatchOneTask();
-    }
-}
-
-Deque<TaskDispatcher<Timer>*>& TaskDispatcher<Timer>::pendingDispatchers()
-{
-    ASSERT(isMainThread());
-    static NeverDestroyed<Deque<TaskDispatcher<Timer>*>> dispatchers;
-    return dispatchers.get();
-}
-
-void TaskDispatcher<Timer>::dispatchOneTask()
-{
-    ASSERT(!m_pendingTasks.isEmpty());
-    std::function<void()> task = m_pendingTasks.takeFirst();
-    task();
-}
-
-}
-
index d541beb..d06d0c1 100644 (file)
@@ -52,17 +52,27 @@ private:
 template<>
 class TaskDispatcher<Timer> {
 public:
-    ~TaskDispatcher();
-    void postTask(std::function<void()>);
+    TaskDispatcher()
+        : m_timer(*this, &TaskDispatcher<Timer>::timerFired)
+    {
+    }
 
-private:
-    static Timer& sharedTimer();
-    static void sharedTimerFired();
-    static Deque<TaskDispatcher<Timer>*>& pendingDispatchers();
+    void postTask(std::function<void()> function)
+    {
+        m_queue.append(function);
+        m_timer.startOneShot(0);
+    }
 
-    void dispatchOneTask();
+    void timerFired()
+    {
+        Deque<std::function<void()>> queue;
+        queue.swap(m_queue);
+        for (std::function<void()>& function : queue)
+            function();
+    }
 
-    Deque<std::function<void()>> m_pendingTasks;
+    Timer m_timer;
+    Deque<std::function<void()>> m_queue;
 };
 
 template <typename T>