OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 25 matching lines...) Expand all Loading... |
36 namespace blink { | 36 namespace blink { |
37 | 37 |
38 // Time intervals are all in seconds. | 38 // Time intervals are all in seconds. |
39 | 39 |
40 class PLATFORM_EXPORT TimerBase { | 40 class PLATFORM_EXPORT TimerBase { |
41 WTF_MAKE_NONCOPYABLE(TimerBase); | 41 WTF_MAKE_NONCOPYABLE(TimerBase); |
42 public: | 42 public: |
43 TimerBase(); | 43 TimerBase(); |
44 virtual ~TimerBase(); | 44 virtual ~TimerBase(); |
45 | 45 |
46 void start(double nextFireInterval, double repeatInterval, const TraceLocati
on&); | 46 virtual void start(double nextFireInterval, double repeatInterval, const Tra
ceLocation&); |
47 | 47 |
48 void startRepeating(double repeatInterval, const TraceLocation& caller) | 48 void startRepeating(double repeatInterval, const TraceLocation& caller) |
49 { | 49 { |
50 start(repeatInterval, repeatInterval, caller); | 50 start(repeatInterval, repeatInterval, caller); |
51 } | 51 } |
52 void startOneShot(double interval, const TraceLocation& caller) | 52 void startOneShot(double interval, const TraceLocation& caller) |
53 { | 53 { |
54 start(interval, 0, caller); | 54 start(interval, 0, caller); |
55 } | 55 } |
56 | 56 |
57 void stop(); | 57 virtual void stop(); |
58 bool isActive() const; | 58 bool isActive() const; |
59 const TraceLocation& location() const { return m_location; } | 59 const TraceLocation& location() const { return m_location; } |
60 | 60 |
61 double nextFireInterval() const; | 61 double nextFireInterval() const; |
62 double nextUnalignedFireInterval() const; | 62 double nextUnalignedFireInterval() const; |
63 double repeatInterval() const { return m_repeatInterval; } | 63 double repeatInterval() const { return m_repeatInterval; } |
64 | 64 |
65 void augmentRepeatInterval(double delta) { | 65 void augmentRepeatInterval(double delta) { |
66 setNextFireTime(m_nextFireTime + delta); | 66 setNextFireTime(m_nextFireTime + delta); |
67 m_repeatInterval += delta; | 67 m_repeatInterval += delta; |
68 } | 68 } |
69 | 69 |
70 void didChangeAlignmentInterval(); | 70 void didChangeAlignmentInterval(); |
71 | 71 |
72 static void fireTimersInNestedEventLoop(); | 72 static void fireTimersInNestedEventLoop(); |
73 | 73 |
| 74 protected: |
| 75 virtual void setNextFireTime(double); |
| 76 |
74 private: | 77 private: |
75 virtual void fired() = 0; | 78 virtual void fired() = 0; |
76 | 79 |
77 virtual double alignedFireTime(double fireTime) const { return fireTime; } | 80 virtual double alignedFireTime(double fireTime) const { return fireTime; } |
78 | 81 |
79 void checkConsistency() const; | 82 void checkConsistency() const; |
80 void checkHeapIndex() const; | 83 void checkHeapIndex() const; |
81 | 84 |
82 void setNextFireTime(double); | |
83 | |
84 bool inHeap() const { return m_heapIndex != -1; } | 85 bool inHeap() const { return m_heapIndex != -1; } |
85 | 86 |
86 bool hasValidHeapPosition() const; | 87 bool hasValidHeapPosition() const; |
87 void updateHeapIfNeeded(double oldTime); | 88 void updateHeapIfNeeded(double oldTime); |
88 | 89 |
89 void heapDecreaseKey(); | 90 void heapDecreaseKey(); |
90 void heapDelete(); | 91 void heapDelete(); |
91 void heapDeleteMin(); | 92 void heapDeleteMin(); |
92 void heapIncreaseKey(); | 93 void heapIncreaseKey(); |
93 void heapInsert(); | 94 void heapInsert(); |
(...skipping 12 matching lines...) Expand all Loading... |
106 | 107 |
107 #if ENABLE(ASSERT) | 108 #if ENABLE(ASSERT) |
108 ThreadIdentifier m_thread; | 109 ThreadIdentifier m_thread; |
109 #endif | 110 #endif |
110 | 111 |
111 friend class ThreadTimers; | 112 friend class ThreadTimers; |
112 friend class TimerHeapLessThanFunction; | 113 friend class TimerHeapLessThanFunction; |
113 friend class TimerHeapReference; | 114 friend class TimerHeapReference; |
114 }; | 115 }; |
115 | 116 |
| 117 class PLATFORM_EXPORT TimerInstanceTracker { |
| 118 public: |
| 119 using TraceMethodTrampoline = void (*)(Visitor*, void*); |
| 120 |
| 121 static void remove(const void*); |
| 122 static void add(const void*, TraceMethodTrampoline); |
| 123 }; |
| 124 |
| 125 template<typename T, bool = IsGarbageCollectedType<T>::value> |
| 126 class TimerKeepAliveTrait { |
| 127 public: |
| 128 static bool protect(bool, const T*) { return false; } |
| 129 static bool unprotect(bool, const void*) { return false; } |
| 130 }; |
| 131 |
| 132 #if ENABLE(OILPAN) |
| 133 template<typename T> |
| 134 class TimerKeepAliveTrait<T, true> { |
| 135 public: |
| 136 static bool protect(bool needsProtection, const T* object) |
| 137 { |
| 138 if (needsProtection) |
| 139 TimerInstanceTracker::add(object, &trampoline); |
| 140 |
| 141 return needsProtection; |
| 142 } |
| 143 |
| 144 static bool unprotect(bool doesNotNeedProtection, const void* object) |
| 145 { |
| 146 if (doesNotNeedProtection) |
| 147 TimerInstanceTracker::remove(object); |
| 148 |
| 149 return doesNotNeedProtection; |
| 150 } |
| 151 |
| 152 private: |
| 153 static void trampoline(Visitor* visitor, void* self) { (reinterpret_cast<T*>
(self)->trace)(visitor); } |
| 154 }; |
| 155 #else |
| 156 // FIXME: Oilpan: remove this specialization when lazy sweeping is enabled on tr
unk. |
| 157 template<typename T> |
| 158 class TimerKeepAliveTrait<T, true> { |
| 159 public: |
| 160 static bool protect(bool, const T*) { return false; } |
| 161 static bool unprotect(bool, const void*) { return false; } |
| 162 }; |
| 163 #endif |
| 164 |
116 template <typename TimerFiredClass> | 165 template <typename TimerFiredClass> |
117 class Timer final : public TimerBase { | 166 class Timer final : public TimerBase { |
118 public: | 167 public: |
119 typedef void (TimerFiredClass::*TimerFiredFunction)(Timer*); | 168 typedef void (TimerFiredClass::*TimerFiredFunction)(Timer*); |
120 | 169 |
121 Timer(TimerFiredClass* o, TimerFiredFunction f) | 170 Timer(TimerFiredClass* o, TimerFiredFunction f) |
122 : m_object(o), m_function(f) { } | 171 : m_object(o) |
| 172 , m_function(f) |
| 173 , m_isKeptAlive(false) |
| 174 { |
| 175 } |
| 176 |
| 177 ~Timer() override |
| 178 { |
| 179 TimerKeepAliveTrait<TimerFiredClass>::unprotect(m_isKeptAlive, m_object)
; |
| 180 } |
| 181 |
| 182 void start(double nextFireInterval, double repeatInterval, const TraceLocati
on& caller) override |
| 183 { |
| 184 TimerBase::start(nextFireInterval, repeatInterval, caller); |
| 185 if (TimerKeepAliveTrait<TimerFiredClass>::protect(!m_isKeptAlive && isAc
tive(), m_object)) |
| 186 m_isKeptAlive = true; |
| 187 } |
| 188 |
| 189 void stop() override |
| 190 { |
| 191 TimerBase::stop(); |
| 192 if (TimerKeepAliveTrait<TimerFiredClass>::unprotect(m_isKeptAlive && !is
Active(), m_object)) |
| 193 m_isKeptAlive = false; |
| 194 } |
123 | 195 |
124 private: | 196 private: |
125 virtual void fired() override { (m_object->*m_function)(this); } | 197 void fired() override |
| 198 { |
| 199 if (TimerKeepAliveTrait<TimerFiredClass>::unprotect(m_isKeptAlive && !is
Active(), m_object)) |
| 200 m_isKeptAlive = false; |
| 201 (m_object->*m_function)(this); |
| 202 } |
| 203 |
| 204 void setNextFireTime(double newUnalignedTime) override |
| 205 { |
| 206 TimerBase::setNextFireTime(newUnalignedTime); |
| 207 if (TimerKeepAliveTrait<TimerFiredClass>::unprotect(m_isKeptAlive && !is
Active(), m_object)) |
| 208 m_isKeptAlive = false; |
| 209 } |
126 | 210 |
127 // FIXME: oilpan: TimerBase should be moved to the heap and m_object should
be traced. | 211 // FIXME: oilpan: TimerBase should be moved to the heap and m_object should
be traced. |
128 // This raw pointer is safe as long as Timer<X> is held by the X itself (Tha
t's the case | 212 // This raw pointer is safe as long as Timer<X> is held by the X itself (Tha
t's the case |
129 // in the current code base). | 213 // in the current code base). |
130 GC_PLUGIN_IGNORE("363031") | 214 GC_PLUGIN_IGNORE("363031") |
131 TimerFiredClass* m_object; | 215 TimerFiredClass* m_object; |
132 TimerFiredFunction m_function; | 216 TimerFiredFunction m_function; |
| 217 bool m_isKeptAlive; |
133 }; | 218 }; |
134 | 219 |
135 inline bool TimerBase::isActive() const | 220 inline bool TimerBase::isActive() const |
136 { | 221 { |
137 ASSERT(m_thread == currentThread()); | 222 ASSERT(m_thread == currentThread()); |
138 return m_nextFireTime; | 223 return m_nextFireTime; |
139 } | 224 } |
140 | 225 |
141 } | 226 } // namespace blink |
142 | 227 |
143 #endif | 228 #endif // Timer_h |
OLD | NEW |