| /* |
| * Copyright (C) 2006 Apple Inc. All rights reserved. |
| * Copyright (C) 2009 Google Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef ThreadTimers_h |
| #define ThreadTimers_h |
| |
| #include <wtf/MonotonicTime.h> |
| #include <wtf/Noncopyable.h> |
| #include <wtf/RefCounted.h> |
| #include <wtf/ThreadSafeRefCounted.h> |
| #include <wtf/Vector.h> |
| |
| namespace WebCore { |
| |
| class SharedTimer; |
| class ThreadTimers; |
| class TimerBase; |
| |
| struct ThreadTimerHeapItem; |
| typedef Vector<RefPtr<ThreadTimerHeapItem>> ThreadTimerHeap; |
| |
| // A collection of timers per thread. Kept in ThreadGlobalData. |
| class ThreadTimers { |
| WTF_MAKE_NONCOPYABLE(ThreadTimers); WTF_MAKE_FAST_ALLOCATED; |
| public: |
| ThreadTimers(); |
| |
| // On a thread different then main, we should set the thread's instance of the SharedTimer. |
| void setSharedTimer(SharedTimer*); |
| |
| ThreadTimerHeap& timerHeap() { return m_timerHeap; } |
| |
| void updateSharedTimer(); |
| void fireTimersInNestedEventLoop(); |
| void breakFireLoopForRenderingUpdate(); |
| |
| unsigned nextHeapInsertionCount() { return m_currentHeapInsertionOrder++; } |
| |
| private: |
| void sharedTimerFiredInternal(); |
| void fireTimersInNestedEventLoopInternal(); |
| |
| ThreadTimerHeap m_timerHeap; |
| SharedTimer* m_sharedTimer { nullptr }; // External object, can be a run loop on a worker thread. Normally set/reset by worker thread. |
| bool m_firingTimers { false }; |
| bool m_shouldBreakFireLoopForRenderingUpdate { false }; |
| unsigned m_currentHeapInsertionOrder { 0 }; |
| MonotonicTime m_pendingSharedTimerFireTime; |
| }; |
| |
| struct ThreadTimerHeapItem : ThreadSafeRefCounted<ThreadTimerHeapItem> { |
| static RefPtr<ThreadTimerHeapItem> create(TimerBase&, MonotonicTime, unsigned); |
| |
| bool hasTimer() const { return m_timer; } |
| TimerBase& timer(); |
| void clearTimer(); |
| |
| ThreadTimerHeap& timerHeap() const; |
| |
| unsigned heapIndex() const; |
| void setHeapIndex(unsigned newIndex); |
| void setNotInHeap() { m_heapIndex = invalidHeapIndex; } |
| |
| bool isInHeap() const { return m_heapIndex != invalidHeapIndex; } |
| bool isFirstInHeap() const { return !m_heapIndex; } |
| |
| MonotonicTime time; |
| unsigned insertionOrder { 0 }; |
| |
| private: |
| ThreadTimers& m_threadTimers; |
| TimerBase* m_timer { nullptr }; |
| unsigned m_heapIndex { invalidHeapIndex }; |
| |
| static const unsigned invalidHeapIndex = static_cast<unsigned>(-1); |
| |
| ThreadTimerHeapItem(TimerBase&, MonotonicTime, unsigned); |
| }; |
| |
| inline TimerBase& ThreadTimerHeapItem::timer() |
| { |
| ASSERT(m_timer); |
| return *m_timer; |
| } |
| |
| inline void ThreadTimerHeapItem::clearTimer() |
| { |
| ASSERT(!isInHeap()); |
| m_timer = nullptr; |
| } |
| |
| inline unsigned ThreadTimerHeapItem::heapIndex() const |
| { |
| ASSERT(m_heapIndex != invalidHeapIndex); |
| return static_cast<unsigned>(m_heapIndex); |
| } |
| |
| inline void ThreadTimerHeapItem::setHeapIndex(unsigned newIndex) |
| { |
| ASSERT(newIndex != invalidHeapIndex); |
| m_heapIndex = newIndex; |
| } |
| |
| inline ThreadTimerHeap& ThreadTimerHeapItem::timerHeap() const |
| { |
| return m_threadTimers.timerHeap(); |
| } |
| |
| } |
| |
| #endif |