class ACE_Time_Value
{
public:
// = Initialization methods.
ACE_Time_Value (long sec = 0, long usec = 0);
ACE_Time_Value (const timeval &t);
// = Friend methods.
// Returns sum of two <ACE_Time_Value>s.
friend ACE_Time_Value operator +
(const ACE_Time_Value &lhs,
const ACE_Time_Value &rhs);
// Returns difference between two
// <ACE_Time_Value>s.
friend ACE_Time_Value operator -
(const ACE_Time_Value &lhs,
const ACE_Time_Value &rhs);
// = operators for normalized <ACE_Time_Value>s.
friend int operator <
(const ACE_Time_Value &lhs,
const ACE_Time_Value &rhs);
// Other relation operators...
private:
// ...
};
Figure 4: Interface for ACE Time Value
ACE_ERROR_RETURN ((LM_ERROR,
"usage: %d"
"time1 time2\n"),
1);
ACE_Time_Value curtime = ACE_OS::gettimeofday ();
ACE_Time_Value timer1 = curtime +
ACE_Time_Value (ACE_OS::atoi (argv[1]));
ACE_Time_Value timer2 = curtime +
ACE_Time_Value (ACE_OS::atoi (argv[2]));
if (timer1 > timer2)
ACE_DEBUG ((LM_DEBUG,
"timer 1 is greater\n"));
else if (timer2 > timer1)
ACE_DEBUG ((LM_DEBUG,
"timer 2 is greater\n"));
else
ACE_DEBUG ((LM_DEBUG,
"timers are equal\n"));
return 0;
}
The code shown above is portable to all OS platforms.
Note how the use of C++ features like wrapper classes and
operator overloading simplifies the use of time-related oper-
ations.
3.1.4 The ACE Timer Queue Class
The ACE Reactor’s timer-based mechanisms are useful
for applications that require timer support. For example,
Web servers require watch-dog timers that release resources
if clients do not send an HTTP request within a specific time
interval after they connect. Likewise, daemon configuration
frameworks like the Windows NT Service Control
Manager [4] require services under their control to peri-
odically report their current status via “heartbeat” messages,
which can be used to restart services that have terminated
abnormally.
The ACE Timer Queue class provides mechanisms that
allow applications to register time-based concrete event
handlers that derive from ACE Event Handler.The
ACE Timer Queue ensures that the handle timeout
method in these event handlers is invoked at an application-
specified time in the future. The methods of the
ACE Timer Queue class illustrated in Figure 5 enable ap-
plications to schedule, cancel, and invoke the timer objects.
class ACE_Timer_Queue
{
public:
// True if queue is empty, else false.
int is_empty (void) const;
// Returns earliest time in queue.
const ACE_Time_Value &earliest_time (void) const;
// Schedule a <handler> to be dispatched at
// the <future_time> and at subsequent
// <interval>s. Returns a timer id that can
// be used to cancel the timer.
virtual long schedule
(ACE_Event_Handler *handler,
const void *act,
const ACE_Time_Value &future_time,
const ACE_Time_Value &interval);
// Cancel all registered <ACE_Event_Handlers>
// that match the address of <handler>, which
// can be registered multiple times.
virtual int cancel (ACE_Event_Handler *handler);
// Cancel the single <ACE_Event_Handler>
// matching the <timer_id> value returned
// from <schedule>.
virtual int cancel (int timer_id,
const void **act = 0);
// Expire all timers <= <expire_time>. This
// method must be called manually since it
// is not invoked asynchronously.
virtual void expire
(const ACE_Time_Value &expire_time);
private:
// ...
};
Figure 5: Interface ACE Timer Queue
An application schedules a concrete event handler to
expire after delay amount of time. If it expires,
the act is passed as the value to the event handler’s
handle timeout hook method. The interval value is
used to reschedule the event handler automatically if it does
not equal ACE Time Value::zero.
The schedule method returns a timer id that uniquely
identifies each event handler’s registration in a timer queue
implementation. The timer id is used by the cancel
method to remove an event handler before it expires. If a
non-NULL act is passed to cancel it is set to the asyn-
chronous completion token (ACT) [9] passed in by the appli-
cation when the timer was originally scheduled. This makes
it possible to delete dynamically allocated ACTs to avoid
memory leaks.
By default, the ACE Timer Queue used by the
ACE Reactor is implemented as a heap. A heap is a
5