1/*
2 * Copyright (C) 2008, 2013 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
27#include "config.h"
28#include "SuspendableTimer.h"
29
30#include "ScriptExecutionContext.h"
31
32namespace WebCore {
33
34SuspendableTimer::SuspendableTimer(ScriptExecutionContext& context)
35 : ActiveDOMObject(&context)
36{
37}
38
39SuspendableTimer::~SuspendableTimer() = default;
40
41bool SuspendableTimer::hasPendingActivity() const
42{
43 return isActive();
44}
45
46void SuspendableTimer::stop()
47{
48 if (!m_suspended)
49 TimerBase::stop();
50
51 // Make it less likely that SuspendableTimer is accidentally revived and fires after being stopped.
52 // It is not allowed for an ActiveDOMObject to become active again after stop().
53 m_suspended = true;
54 m_savedIsActive = false;
55
56 didStop();
57}
58
59void SuspendableTimer::suspend(ReasonForSuspension)
60{
61 ASSERT(!m_suspended);
62 m_suspended = true;
63
64 m_savedIsActive = TimerBase::isActive();
65 if (m_savedIsActive) {
66 m_savedNextFireInterval = TimerBase::nextUnalignedFireInterval();
67 m_savedRepeatInterval = TimerBase::repeatInterval();
68 TimerBase::stop();
69 }
70}
71
72void SuspendableTimer::resume()
73{
74 ASSERT(m_suspended);
75 m_suspended = false;
76
77 if (m_savedIsActive)
78 start(m_savedNextFireInterval, m_savedRepeatInterval);
79}
80
81bool SuspendableTimer::canSuspendForDocumentSuspension() const
82{
83 return true;
84}
85
86void SuspendableTimer::didStop()
87{
88}
89
90void SuspendableTimer::cancel()
91{
92 if (!m_suspended)
93 TimerBase::stop();
94 else
95 m_suspended = false;
96}
97
98void SuspendableTimer::startRepeating(Seconds repeatInterval)
99{
100 if (!m_suspended)
101 TimerBase::startRepeating(repeatInterval);
102 else {
103 m_savedIsActive = true;
104 m_savedNextFireInterval = repeatInterval;
105 m_savedRepeatInterval = repeatInterval;
106 }
107}
108
109void SuspendableTimer::startOneShot(Seconds interval)
110{
111 if (!m_suspended)
112 TimerBase::startOneShot(interval);
113 else {
114 m_savedIsActive = true;
115 m_savedNextFireInterval = interval;
116 m_savedRepeatInterval = 0_s;
117 }
118}
119
120Seconds SuspendableTimer::repeatInterval() const
121{
122 if (!m_suspended)
123 return TimerBase::repeatInterval();
124 if (m_savedIsActive)
125 return m_savedRepeatInterval;
126 return 0_s;
127}
128
129void SuspendableTimer::augmentFireInterval(Seconds delta)
130{
131 if (!m_suspended)
132 TimerBase::augmentFireInterval(delta);
133 else if (m_savedIsActive) {
134 m_savedNextFireInterval += delta;
135 } else {
136 m_savedIsActive = true;
137 m_savedNextFireInterval = delta;
138 m_savedRepeatInterval = 0_s;
139 }
140}
141
142void SuspendableTimer::augmentRepeatInterval(Seconds delta)
143{
144 if (!m_suspended)
145 TimerBase::augmentRepeatInterval(delta);
146 else if (m_savedIsActive) {
147 m_savedNextFireInterval += delta;
148 m_savedRepeatInterval += delta;
149 } else {
150 m_savedIsActive = true;
151 m_savedNextFireInterval = delta;
152 m_savedRepeatInterval = delta;
153 }
154}
155
156} // namespace WebCore
157