Improve DeadlineTimer

This commit is contained in:
Vinnie Falco
2013-07-10 08:36:04 -07:00
parent 3ff1c41a67
commit bca90f2110
2 changed files with 54 additions and 14 deletions

View File

@@ -43,11 +43,24 @@ public:
bassert (m_items.empty ()); bassert (m_items.empty ());
} }
void activate (DeadlineTimer* timer) // Okay to call on an active timer.
// However, an extra notification may still happen due to concurrency.
//
void activate (DeadlineTimer* timer, double secondsRecurring, Time const& when)
{ {
bassert (secondsRecurring >= 0);
LockType::ScopedLockType lock (m_mutex); LockType::ScopedLockType lock (m_mutex);
bassert (! timer->m_isActive); if (timer->m_isActive)
{
m_items.erase (m_items.iterator_to (*timer));
timer->m_isActive = false;
}
timer->m_secondsRecurring = secondsRecurring;
timer->m_notificationTime = when;
insertSorted (*timer); insertSorted (*timer);
timer->m_isActive = true; timer->m_isActive = true;
@@ -219,26 +232,25 @@ DeadlineTimer::~DeadlineTimer ()
void DeadlineTimer::setExpiration (double secondsUntilDeadline) void DeadlineTimer::setExpiration (double secondsUntilDeadline)
{ {
m_secondsRecurring = 0; bassert (secondsUntilDeadline > 0);
m_notificationTime = Time::getCurrentTime () + RelativeTime (secondsUntilDeadline);
m_manager->activate (this); Time const when = Time::getCurrentTime () + RelativeTime (secondsUntilDeadline);
m_manager->activate (this, 0, when);
} }
void DeadlineTimer::setRecurringExpiration (double secondsUntilDeadline) void DeadlineTimer::setRecurringExpiration (double secondsUntilDeadline)
{ {
m_secondsRecurring = secondsUntilDeadline; bassert (secondsUntilDeadline > 0);
m_notificationTime = Time::getCurrentTime () + RelativeTime (secondsUntilDeadline);
m_manager->activate (this); Time const when = Time::getCurrentTime () + RelativeTime (secondsUntilDeadline);
m_manager->activate (this, secondsUntilDeadline, when);
} }
void DeadlineTimer::setExpirationTime (Time absoluteDeadline) void DeadlineTimer::setExpirationTime (Time const& when)
{ {
m_secondsRecurring = 0; m_manager->activate (this, 0, when);
m_notificationTime = absoluteDeadline;
m_manager->activate (this);
} }
void DeadlineTimer::reset () void DeadlineTimer::reset ()

View File

@@ -46,21 +46,49 @@ public:
~DeadlineTimer (); ~DeadlineTimer ();
/** Set the timer to go off once in the future. /** Set the timer to go off once in the future.
If the timer is already active, this will reset it.
@note If the timer is already active, a notification may still
occur due to concurrency.
@param secondsUntilDeadline The number of seconds until the timer
will send a notification. This must be
greater than zero.
*/ */
void setExpiration (double secondsUntilDeadline); void setExpiration (double secondsUntilDeadline);
/** Set the timer to go off repeatedly with the specified frequency. /** Set the timer to go off repeatedly with the specified frequency.
If the timer is already active, this will reset it.
@note If the timer is already active, a notification may still
occur due to concurrency.
@param secondsUntilDeadline The number of seconds until the timer
will send a notification. This must be
greater than zero.
*/ */
void setRecurringExpiration (double secondsUntilDeadline); void setRecurringExpiration (double secondsUntilDeadline);
/** Set the timer to go off at a specific time. /** Set the timer to go off at a specific time.
If the timer is already active, this will reset it.
@note If the timer is already active, a notification may still
occur due to concurrency.
@note If the time is in the past, the timer will go off @note If the time is in the past, the timer will go off
immediately. immediately.
*/ */
void setExpirationTime (Time absoluteDeadline); void setExpirationTime (Time const& when);
/** Reset the timer so that no more notifications are sent. /** Reset the timer so that no more notifications are sent.
It is okay to call this on an inactive timer.
@note If the timer is already active, a notification may still
occur due to concurrency.
*/ */
void reset (); void reset ();