Add support for Device Orientation / Motion permission API
[WebKit-https.git] / Source / WebCore / dom / Microtasks.cpp
1 /*
2  * Copyright (C) 2014 Yoav Weiss (yoav@yoav.ws)
3  * Copyright (C) 2015 Akamai Technologies Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  */
21
22 #include "config.h"
23 #include "Microtasks.h"
24
25 #include "WorkerGlobalScope.h"
26 #include <wtf/MainThread.h>
27 #include <wtf/NeverDestroyed.h>
28 #include <wtf/SetForScope.h>
29
30 namespace WebCore {
31
32 void Microtask::removeSelfFromQueue(MicrotaskQueue& queue)
33 {
34     queue.remove(*this);
35 }
36
37 MicrotaskQueue::MicrotaskQueue()
38     : m_timer(*this, &MicrotaskQueue::timerFired)
39 {
40 }
41
42 MicrotaskQueue::~MicrotaskQueue() = default;
43
44 MicrotaskQueue& MicrotaskQueue::mainThreadQueue()
45 {
46     ASSERT(isMainThread());
47     static NeverDestroyed<MicrotaskQueue> queue;
48     return queue;
49 }
50
51 MicrotaskQueue& MicrotaskQueue::contextQueue(ScriptExecutionContext& context)
52 {
53     // While main thread has many ScriptExecutionContexts, WorkerGlobalScope and worker thread have
54     // one on one correspondence. The lifetime of MicrotaskQueue is aligned to this semantics.
55     // While main thread MicrotaskQueue is persistently held, worker's MicrotaskQueue is held by
56     // WorkerGlobalScope.
57     if (isMainThread())
58         return mainThreadQueue();
59     return downcast<WorkerGlobalScope>(context).microtaskQueue();
60 }
61
62 void MicrotaskQueue::append(std::unique_ptr<Microtask>&& task)
63 {
64     m_microtaskQueue.append(WTFMove(task));
65
66     m_timer.startOneShot(0_s);
67 }
68
69 void MicrotaskQueue::remove(const Microtask& task)
70 {
71     for (size_t i = 0; i < m_microtaskQueue.size(); ++i) {
72         if (m_microtaskQueue[i].get() == &task) {
73             m_microtaskQueue.remove(i);
74             return;
75         }
76     }
77 }
78
79 void MicrotaskQueue::timerFired()
80 {
81     performMicrotaskCheckpoint();
82 }
83
84 void MicrotaskQueue::performMicrotaskCheckpoint()
85 {
86     if (m_performingMicrotaskCheckpoint)
87         return;
88
89     SetForScope<bool> change(m_performingMicrotaskCheckpoint, true);
90
91     Vector<std::unique_ptr<Microtask>> toKeep;
92     while (!m_microtaskQueue.isEmpty()) {
93         Vector<std::unique_ptr<Microtask>> queue = WTFMove(m_microtaskQueue);
94         for (auto& task : queue) {
95             auto result = task->run();
96             switch (result) {
97             case Microtask::Result::Done:
98                 break;
99             case Microtask::Result::KeepInQueue:
100                 toKeep.append(WTFMove(task));
101                 break;
102             }
103         }
104     }
105
106     m_microtaskQueue = WTFMove(toKeep);
107 }
108
109 } // namespace WebCore