Delete WebMetal implementation in favor of WebGPU
[WebKit-https.git] / Source / WebCore / platform / Timer.h
1 /*
2  * Copyright (C) 2006 Apple Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #pragma once
27
28 #include "ThreadTimers.h"
29 #include <functional>
30 #include <wtf/Function.h>
31 #include <wtf/MonotonicTime.h>
32 #include <wtf/Noncopyable.h>
33 #include <wtf/Optional.h>
34 #include <wtf/Seconds.h>
35 #include <wtf/Threading.h>
36 #include <wtf/Vector.h>
37 #include <wtf/WeakPtr.h>
38
39 #if PLATFORM(IOS_FAMILY)
40 #include "WebCoreThread.h"
41 #endif
42
43 namespace WebCore {
44
45 class TimerBase {
46     WTF_MAKE_NONCOPYABLE(TimerBase);
47     WTF_MAKE_FAST_ALLOCATED;
48 public:
49     WEBCORE_EXPORT TimerBase();
50     WEBCORE_EXPORT virtual ~TimerBase();
51
52     WEBCORE_EXPORT void start(Seconds nextFireInterval, Seconds repeatInterval);
53
54     void startRepeating(Seconds repeatInterval) { start(repeatInterval, repeatInterval); }
55     void startOneShot(Seconds interval) { start(interval, 0_s); }
56
57     WEBCORE_EXPORT void stop();
58     bool isActive() const;
59
60     Seconds nextFireInterval() const;
61     Seconds nextUnalignedFireInterval() const;
62     Seconds repeatInterval() const { return m_repeatInterval; }
63
64     void augmentFireInterval(Seconds delta) { setNextFireTime(m_heapItem->time + delta); }
65     void augmentRepeatInterval(Seconds delta) { augmentFireInterval(delta); m_repeatInterval += delta; }
66
67     void didChangeAlignmentInterval();
68
69     static void fireTimersInNestedEventLoop();
70
71 private:
72     virtual void fired() = 0;
73
74     virtual Optional<MonotonicTime> alignedFireTime(MonotonicTime) const { return WTF::nullopt; }
75
76     void checkConsistency() const;
77     void checkHeapIndex() const;
78
79     void setNextFireTime(MonotonicTime);
80
81     bool inHeap() const { return m_heapItem && m_heapItem->isInHeap(); }
82
83     bool hasValidHeapPosition() const;
84     void updateHeapIfNeeded(MonotonicTime oldTime);
85
86     void heapDecreaseKey();
87     void heapDelete();
88     void heapDeleteMin();
89     void heapIncreaseKey();
90     void heapInsert();
91     void heapPop();
92     void heapPopMin();
93     static void heapDeleteNullMin(ThreadTimerHeap&);
94
95     MonotonicTime nextFireTime() const { return m_heapItem ? m_heapItem->time : MonotonicTime { }; }
96
97     MonotonicTime m_unalignedNextFireTime; // m_nextFireTime not considering alignment interval
98     Seconds m_repeatInterval; // 0 if not repeating
99
100     RefPtr<ThreadTimerHeapItem> m_heapItem;
101     Ref<Thread> m_thread { Thread::current() };
102
103     friend class ThreadTimers;
104     friend class TimerHeapLessThanFunction;
105     friend class TimerHeapReference;
106 };
107
108
109 class Timer : public TimerBase {
110     WTF_MAKE_FAST_ALLOCATED;
111 public:
112     template <typename TimerFiredClass, typename TimerFiredBaseClass>
113     Timer(TimerFiredClass& object, void (TimerFiredBaseClass::*function)())
114         : m_function(std::bind(function, &object))
115     {
116     }
117
118     Timer(WTF::Function<void ()>&& function)
119         : m_function(WTFMove(function))
120     {
121     }
122
123 private:
124     void fired() override
125     {
126         m_function();
127     }
128     
129     WTF::Function<void ()> m_function;
130 };
131
132 inline bool TimerBase::isActive() const
133 {
134     // FIXME: Write this in terms of USE(WEB_THREAD) instead of PLATFORM(IOS_FAMILY).
135 #if !PLATFORM(IOS_FAMILY)
136     ASSERT(m_thread.ptr() == &Thread::current());
137 #else
138     ASSERT(WebThreadIsCurrent() || pthread_main_np() || m_thread.ptr() == &Thread::current());
139 #endif // PLATFORM(IOS_FAMILY)
140     return static_cast<bool>(nextFireTime());
141 }
142
143 class DeferrableOneShotTimer : protected TimerBase {
144     WTF_MAKE_FAST_ALLOCATED;
145 public:
146     template<typename TimerFiredClass>
147     DeferrableOneShotTimer(TimerFiredClass& object, void (TimerFiredClass::*function)(), Seconds delay)
148         : DeferrableOneShotTimer(std::bind(function, &object), delay)
149     {
150     }
151
152     DeferrableOneShotTimer(WTF::Function<void ()>&& function, Seconds delay)
153         : m_function(WTFMove(function))
154         , m_delay(delay)
155         , m_shouldRestartWhenTimerFires(false)
156     {
157     }
158
159     void restart()
160     {
161         // Setting this boolean is much more efficient than calling startOneShot
162         // again, which might result in rescheduling the system timer which
163         // can be quite expensive.
164
165         if (isActive()) {
166             m_shouldRestartWhenTimerFires = true;
167             return;
168         }
169         startOneShot(m_delay);
170     }
171
172     void stop()
173     {
174         m_shouldRestartWhenTimerFires = false;
175         TimerBase::stop();
176     }
177
178     using TimerBase::isActive;
179
180 private:
181     void fired() override
182     {
183         if (m_shouldRestartWhenTimerFires) {
184             m_shouldRestartWhenTimerFires = false;
185             startOneShot(m_delay);
186             return;
187         }
188
189         m_function();
190     }
191
192     WTF::Function<void ()> m_function;
193
194     Seconds m_delay;
195     bool m_shouldRestartWhenTimerFires;
196 };
197
198 }