15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef Timer_h
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define Timer_h
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/PlatformExport.h"
30d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "platform/TraceLocation.h"
31f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "platform/heap/Handle.h"
327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/Noncopyable.h"
337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/Threading.h"
347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/Vector.h"
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Time intervals are all in seconds.
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)class PLATFORM_EXPORT TimerBase {
415d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    WTF_MAKE_NONCOPYABLE(TimerBase); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TimerBase();
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual ~TimerBase();
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
46d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    void start(double nextFireInterval, double repeatInterval, const TraceLocation&);
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    void startRepeating(double repeatInterval, const TraceLocation& caller)
49d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
50d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        start(repeatInterval, repeatInterval, caller);
51d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    void startOneShot(double interval, const TraceLocation& caller)
53d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
54d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        start(interval, 0, caller);
55d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void stop();
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isActive() const;
59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const TraceLocation& location() const { return m_location; }
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double nextFireInterval() const;
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double nextUnalignedFireInterval() const;
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double repeatInterval() const { return m_repeatInterval; }
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    void augmentRepeatInterval(double delta) {
6653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        setNextFireTime(m_nextFireTime + delta);
6753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_repeatInterval += delta;
6853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void didChangeAlignmentInterval();
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static void fireTimersInNestedEventLoop();
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void fired() = 0;
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual double alignedFireTime(double fireTime) const { return fireTime; }
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void checkConsistency() const;
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void checkHeapIndex() const;
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setNextFireTime(double);
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool inHeap() const { return m_heapIndex != -1; }
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool hasValidHeapPosition() const;
87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    void updateHeapIfNeeded(double oldTime);
88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void heapDecreaseKey();
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void heapDelete();
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void heapDeleteMin();
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void heapIncreaseKey();
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void heapInsert();
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void heapPop();
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void heapPopMin();
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Vector<TimerBase*>& timerHeap() const { ASSERT(m_cachedThreadGlobalTimerHeap); return *m_cachedThreadGlobalTimerHeap; }
98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m_nextFireTime; // 0 if inactive
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m_unalignedNextFireTime; // m_nextFireTime not considering alignment interval
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m_repeatInterval; // 0 if not repeating
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_heapIndex; // -1 if not in heap
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned m_heapInsertionOrder; // Used to keep order among equal-fire-time timers
104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Vector<TimerBase*>* m_cachedThreadGlobalTimerHeap;
105d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    TraceLocation m_location;
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
107197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ThreadIdentifier m_thread;
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    friend class ThreadTimers;
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    friend class TimerHeapLessThanFunction;
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    friend class TimerHeapReference;
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)template <typename TimerFiredClass>
11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class Timer FINAL : public TimerBase {
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    typedef void (TimerFiredClass::*TimerFiredFunction)(Timer*);
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Timer(TimerFiredClass* o, TimerFiredFunction f)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_object(o), m_function(f) { }
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual void fired() OVERRIDE { (m_object->*m_function)(this); }
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1276f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // FIXME: oilpan: TimerBase should be moved to the heap and m_object should be traced.
1286f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // This raw pointer is safe as long as Timer<X> is held by the X itself (That's the case
1296f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // in the current code base).
130f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    GC_PLUGIN_IGNORE("363031")
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TimerFiredClass* m_object;
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TimerFiredFunction m_function;
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool TimerBase::isActive() const
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_thread == currentThread());
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_nextFireTime;
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)template <typename TimerFiredClass>
14209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class DeferrableOneShotTimer FINAL : private TimerBase {
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    typedef void (TimerFiredClass::*TimerFiredFunction)(DeferrableOneShotTimer*);
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DeferrableOneShotTimer(TimerFiredClass* o, TimerFiredFunction f, double delay)
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_object(o)
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_function(f)
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_delay(delay)
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_shouldRestartWhenTimerFires(false)
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
154d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    void restart(const TraceLocation& caller)
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Setting this boolean is much more efficient than calling startOneShot
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // again, which might result in rescheduling the system timer which
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // can be quite expensive.
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isActive()) {
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_shouldRestartWhenTimerFires = true;
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
164d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        startOneShot(m_delay, caller);
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    using TimerBase::stop;
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    using TimerBase::isActive;
1691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
17109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual void fired() OVERRIDE
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_shouldRestartWhenTimerFires) {
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_shouldRestartWhenTimerFires = false;
175d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // FIXME: This should not be FROM_HERE.
176d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            startOneShot(m_delay, FROM_HERE);
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        (m_object->*m_function)(this);
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1836f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // FIXME: oilpan: TimerBase should be moved to the heap and m_object should be traced.
1846f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // This raw pointer is safe as long as Timer<X> is held by the X itself (That's the case
1856f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // in the current code base).
186f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    GC_PLUGIN_IGNORE("363031")
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TimerFiredClass* m_object;
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TimerFiredFunction m_function;
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double m_delay;
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_shouldRestartWhenTimerFires;
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
197