| 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 |