summaryrefslogtreecommitdiff
path: root/examples/APG/Timers
diff options
context:
space:
mode:
authorSteve Huston <shuston@riverace.com>2004-01-01 21:01:01 +0000
committerSteve Huston <shuston@riverace.com>2004-01-01 21:01:01 +0000
commit6649a1a542c18bd756757a2d58f3ea51eea0cc47 (patch)
tree15b88279a4187c88c37adabba8740a0165139299 /examples/APG/Timers
parentfcf24b2de58a080db0617c641f337298614a944b (diff)
downloadATCD-6649a1a542c18bd756757a2d58f3ea51eea0cc47.tar.gz
ChangeLogTag:Thu Jan 1 15:20:30 2004 Steve Huston <shuston@riverace.com>
Diffstat (limited to 'examples/APG/Timers')
-rw-r--r--examples/APG/Timers/Alarm.cpp51
-rw-r--r--examples/APG/Timers/CB.cpp62
-rw-r--r--examples/APG/Timers/CB.h36
-rw-r--r--examples/APG/Timers/Makefile36
-rw-r--r--examples/APG/Timers/Makefile.singles14
-rw-r--r--examples/APG/Timers/Makefile.timers14
-rw-r--r--examples/APG/Timers/Makefile.upcall14
-rw-r--r--examples/APG/Timers/PCB.cpp70
-rw-r--r--examples/APG/Timers/PCB.h28
-rw-r--r--examples/APG/Timers/PTimerDispatcher.cpp64
-rw-r--r--examples/APG/Timers/PTimerDispatcher.h39
-rw-r--r--examples/APG/Timers/Task.cpp69
-rw-r--r--examples/APG/Timers/TimerDispatcher.cpp68
-rw-r--r--examples/APG/Timers/TimerDispatcher.h40
-rw-r--r--examples/APG/Timers/Timers.cpp57
-rw-r--r--examples/APG/Timers/Upcall.cpp75
-rw-r--r--examples/APG/Timers/Upcall.h44
-rw-r--r--examples/APG/Timers/timers.mpc31
-rw-r--r--examples/APG/Timers/timers.mwc3
19 files changed, 815 insertions, 0 deletions
diff --git a/examples/APG/Timers/Alarm.cpp b/examples/APG/Timers/Alarm.cpp
new file mode 100644
index 00000000000..ae79b5feefd
--- /dev/null
+++ b/examples/APG/Timers/Alarm.cpp
@@ -0,0 +1,51 @@
+// $Id$
+
+// Listing 1 code/ch20
+#include "ace/Timer_Queue_Adapters.h"
+#include "ace/Timer_Heap.h"
+
+typedef ACE_Async_Timer_Queue_Adapter<ACE_Timer_Heap> Timer;
+// Listing 1
+
+class CB : public ACE_Event_Handler
+{
+public:
+ CB (int id) : id_(id) { }
+
+ virtual int handle_timeout (const ACE_Time_Value &,
+ const void *arg)
+ {
+ ACE_TRACE (ACE_TEXT ("CB::handle_timeout"));
+
+ const int *val = ACE_static_cast (const int*, arg);
+ ACE_ASSERT ((*val) == id_);
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Timer expired\n")));
+ return 0;
+ }
+
+private:
+ int id_;
+};
+
+// Listing 2 code/ch20
+int ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ // Create the timer such that it blocks all signals
+ // when it goes off.
+ Timer timer;
+
+ // Schedule a timer to go off 2 seconds later and then
+ // after every 4 seconds.
+ CB cb (1);
+ int arg = 1;
+ ACE_Time_Value initial (2);
+ ACE_Time_Value repeat (4);
+ initial += ACE_OS::gettimeofday ();
+ timer.schedule (&cb, &arg, initial, repeat);
+
+ while (1) // Don't let the main thread exit.
+ ACE_OS::sleep (2);
+ return 0; // Not reached.
+}
+// Listing 2
diff --git a/examples/APG/Timers/CB.cpp b/examples/APG/Timers/CB.cpp
new file mode 100644
index 00000000000..329fed58a4b
--- /dev/null
+++ b/examples/APG/Timers/CB.cpp
@@ -0,0 +1,62 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "CB.h"
+#include "TimerDispatcher.h"
+
+CB::CB () : count_(0)
+{
+ ACE_TRACE (ACE_TEXT ("CB::CB"));
+}
+
+// Listing 1 code/ch20
+int CB::handle_timeout (const ACE_Time_Value &,
+ const void *arg)
+{
+ ACE_TRACE (ACE_TEXT ("CB::handle_timeout"));
+
+ const int *val = ACE_static_cast (const int*, arg);
+ ACE_ASSERT ((*val) == timerID_);
+ if (count_ == 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Reseting interval for timer %d\n"),
+ timerID_));
+
+ // New interval is 10 ms.
+ ACE_Time_Value interval (0L, 1000L);
+ ACE_ASSERT (Timer::instance ()->reset_interval
+ (timerID_, interval) != -1);
+ }
+
+ if (count_++ == 10)
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Canceling %d\n"),
+ timerID_));
+ ACE_ASSERT ((Timer::instance ()->cancel (this)) != 0);
+ }
+
+ return 0;
+}
+// Listing 1
+
+void
+CB::setID (long timerID)
+{
+ ACE_TRACE (ACE_TEXT ("CB::setID"));
+ timerID_ = timerID;
+}
+
+long
+CB::getID (void)
+{
+ ACE_TRACE (ACE_TEXT ("CB::getID"));
+ return timerID_;
+}
+
+int
+CB::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
+{
+ ACE_TRACE (ACE_TEXT ("CB::handle_close"));
+ return 0;
+}
diff --git a/examples/APG/Timers/CB.h b/examples/APG/Timers/CB.h
new file mode 100644
index 00000000000..716ad4e4f50
--- /dev/null
+++ b/examples/APG/Timers/CB.h
@@ -0,0 +1,36 @@
+/* -*- C++ -*- */
+// $Id$
+
+#if !defined(CB_H)
+#define CB_H
+
+#include "ace/Event_Handler.h"
+
+#include "TimerDispatcher.h"
+
+// Listing 1 code/ch20
+class CB : public ACE_Event_Handler
+{
+public:
+ CB ();
+
+ // Set the timer id that is being handled by this instance.
+ void setID (long timerID);
+
+ // Get the timer id.
+ long getID (void);
+
+ // Handle the timeout.
+ virtual int handle_timeout(const ACE_Time_Value &tv,
+ const void *arg = 0);
+
+ virtual int handle_close (ACE_HANDLE handle,
+ ACE_Reactor_Mask close_mask);
+
+private:
+ long timerID_;
+ int count_;
+};
+// Listing 1
+
+#endif /*CB_H*/
diff --git a/examples/APG/Timers/Makefile b/examples/APG/Timers/Makefile
new file mode 100644
index 00000000000..37590afa196
--- /dev/null
+++ b/examples/APG/Timers/Makefile
@@ -0,0 +1,36 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+MAKEFILE=Makefile
+
+MKLIST = Makefile.singles \
+ Makefile.timers \
+ Makefile.upcall
+
+## Ensure that Makefiles in MKLIST are executed in sequence during a
+## parallel build because we share some files between multiple libraries.
+.NOTPARALLEL:
+
+## Makefile.Reactive_Logging_Server.mkfile is a dummy target which will cause
+## $(MAKE) -f Makefile.Reactive_Logging_Server to be invoked, then it cleans
+## up tempinc when needed for AIX Visual Age C++.
+%.mkfile: %
+ @echo $(MAKE) -f $< $(MKFILE_TARGET)
+ @$(MAKE) -f $< $(MKFILE_TARGET)
+ -@$(RM) -rf tempinc
+
+# This rule invokes make again with the list of .mkfile targets as a
+# parameter. For example, if the all target is being made, make is invoked
+# as follows:
+#
+# make -f Makefile MKFILE_TARGET=all Makefile.singles
+
+all clean depend realclean html:
+ifneq ($(MKLIST),)
+ @echo $(MAKE) -f $(MAKEFILE) MKFILE_TARGET=$@ $(addsuffix .mkfile, $(MKLIST))
+ @$(MAKE) -f $(MAKEFILE) MKFILE_TARGET=$@ $(addsuffix .mkfile, $(MKLIST))
+endif
+
+# DO NOT DELETE THIS LINE -- g++dep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
diff --git a/examples/APG/Timers/Makefile.singles b/examples/APG/Timers/Makefile.singles
new file mode 100644
index 00000000000..cc857d6c4ba
--- /dev/null
+++ b/examples/APG/Timers/Makefile.singles
@@ -0,0 +1,14 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Alarm Task
+
+BUILD = $(VBIN)
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Timers/Makefile.timers b/examples/APG/Timers/Makefile.timers
new file mode 100644
index 00000000000..4d63a0c56cb
--- /dev/null
+++ b/examples/APG/Timers/Makefile.timers
@@ -0,0 +1,14 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Timers
+
+SRC = Timers.cpp CB.cpp TimerDispatcher.cpp
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Timers/Makefile.upcall b/examples/APG/Timers/Makefile.upcall
new file mode 100644
index 00000000000..859a20278c7
--- /dev/null
+++ b/examples/APG/Timers/Makefile.upcall
@@ -0,0 +1,14 @@
+# $Id$
+#
+# Copyright 2003 Addison-Wesley Inc. All Rights Reserved.
+
+BIN = Upcall
+
+SRC = Upcall.cpp PCB.cpp PTimerDispatcher.cpp
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
diff --git a/examples/APG/Timers/PCB.cpp b/examples/APG/Timers/PCB.cpp
new file mode 100644
index 00000000000..ce5c8d556f3
--- /dev/null
+++ b/examples/APG/Timers/PCB.cpp
@@ -0,0 +1,70 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "PCB.h"
+#include "PTimerDispatcher.h"
+
+PCB::PCB() : count_(0)
+{
+ ACE_TRACE (ACE_TEXT ("PCB::PCB"));
+}
+
+int PCB::handleEvent (const void *arg)
+{
+ ACE_TRACE (ACE_TEXT ("PCB::handle_timeout"));
+
+ const int *val = ACE_static_cast(const int*, arg);
+ ACE_ASSERT ((*val) == timerID_);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT("Timer %d expiry handled by thread %t\n"),
+ timerID_));
+ if (count_ == 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Reseting interval for timer %d\n"),
+ timerID_));
+
+ // New interval is 10 ms.
+ ACE_Time_Value interval (0L, 1000L);
+ ACE_ASSERT (PTimer::instance ()->reset_interval
+ (timerID_, interval) != -1);
+ }
+
+ if (count_++ == 10)
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Canceling %d\n"),
+ timerID_));
+ ACE_ASSERT ((PTimer::instance ()->cancel (this)) != 0);
+ }
+
+ return 0;
+}
+
+void
+PCB::setID (long timerID)
+{
+ ACE_TRACE (ACE_TEXT ("PCB::setID"));
+ timerID_ = timerID;
+}
+
+long
+PCB::getID (void)
+{
+ ACE_TRACE (ACE_TEXT ("PCB::getID"));
+ return timerID_;
+}
+
+int
+PCB::handleClose (void)
+{
+ ACE_TRACE (ACE_TEXT ("PCB::handle_close"));
+ return 0;
+}
+
+int
+PCB::handleCancel (void)
+{
+ ACE_TRACE (ACE_TEXT ("PCB::handleCancel"));
+ return 0;
+}
diff --git a/examples/APG/Timers/PCB.h b/examples/APG/Timers/PCB.h
new file mode 100644
index 00000000000..9f82e4652cd
--- /dev/null
+++ b/examples/APG/Timers/PCB.h
@@ -0,0 +1,28 @@
+/* -*- C++ -*- */
+// $Id$
+
+#if !defined(PCB_H)
+#define PCB_H
+
+// Listing 1 code/ch20
+class PCB
+{
+public:
+ PCB ();
+
+ // Set/get the timer id that is being handled by this instance.
+ void setID (long timerID);
+ long getID (void);
+
+ // Handle a timeout event, cancel, and close.
+ virtual int handleEvent (const void *arg);
+ virtual int handleCancel (void);
+ virtual int handleClose (void);
+
+private:
+ long timerID_;
+ int count_;
+};
+// Listing 1
+
+#endif /*PCB_H*/
diff --git a/examples/APG/Timers/PTimerDispatcher.cpp b/examples/APG/Timers/PTimerDispatcher.cpp
new file mode 100644
index 00000000000..50a51b99115
--- /dev/null
+++ b/examples/APG/Timers/PTimerDispatcher.cpp
@@ -0,0 +1,64 @@
+// $Id$
+
+#include "PTimerDispatcher.h"
+
+void PTimer_Dispatcher::wait_for_event (void)
+{
+ ACE_TRACE (ACE_TEXT ("PTimer_Dispatcher::wait_for_event"));
+
+ while (1)
+ {
+ ACE_Time_Value max_tv = timer_queue_->gettimeofday ();
+
+ ACE_Time_Value *this_timeout =
+ this->timer_queue_->calculate_timeout (&max_tv);
+
+ if (*this_timeout == ACE_Time_Value::zero)
+ this->timer_queue_->expire ();
+ else
+ {
+ // Convert to absolute time.
+ ACE_Time_Value next_timeout =
+ timer_queue_->gettimeofday ();
+ next_timeout += *this_timeout;
+ if (this->timer_.wait (&next_timeout) == -1 )
+ this->timer_queue_->expire ();
+ }
+ }
+}
+
+long
+PTimer_Dispatcher::schedule (PCB *cb,
+ void *arg,
+ const ACE_Time_Value &abs_time,
+ const ACE_Time_Value &interval)
+{
+ ACE_TRACE (ACE_TEXT ("PTimer_Dispatcher::schedule_timer"));
+
+ return this->timer_queue_->schedule
+ (cb, arg, abs_time, interval);
+}
+
+int
+PTimer_Dispatcher::cancel (PCB *cb,
+ int dont_call_handle_close)
+{
+ ACE_TRACE (ACE_TEXT ("PTimer_Dispatcher::cancel"));
+ return timer_queue_->cancel (cb, dont_call_handle_close);
+}
+
+void PTimer_Dispatcher::set (PTimerQueue *timer_queue)
+{
+ ACE_TRACE (ACE_TEXT ("PTimer_Dispatcher::set"));
+
+ timer_queue_ = timer_queue;
+}
+
+int
+PTimer_Dispatcher::reset_interval (long timer_id,
+ const ACE_Time_Value &interval)
+{
+ ACE_TRACE (ACE_TEXT ("PTimer_Dispatcher::reset_interval"));
+
+ return timer_queue_->reset_interval (timer_id, interval);
+}
diff --git a/examples/APG/Timers/PTimerDispatcher.h b/examples/APG/Timers/PTimerDispatcher.h
new file mode 100644
index 00000000000..8a530f41709
--- /dev/null
+++ b/examples/APG/Timers/PTimerDispatcher.h
@@ -0,0 +1,39 @@
+/* -*- C++ -*- */
+// $Id$
+
+#if !defined(PTIMER_DISPATCHER_H)
+#define PTIMER_DISPATCHER_H
+
+#include "ace/Singleton.h"
+#include "ace/Synch.h" // needed for ACE_Event
+
+#include "Upcall.h"
+class PCB;
+
+class PTimer_Dispatcher
+{
+public:
+ void wait_for_event (void);
+
+ long schedule (PCB *cb,
+ void *arg,
+ const ACE_Time_Value &abs_time,
+ const ACE_Time_Value &interval);
+
+ int cancel (PCB *cb,
+ int dont_call_handle_close = 1);
+
+ int reset_interval (long timer_id,
+ const ACE_Time_Value &interval);
+
+ void set (PTimerQueue *timer_queue);
+
+private:
+ PTimerQueue *timer_queue_;
+ ACE_Event timer_;
+};
+
+typedef ACE_Singleton<PTimer_Dispatcher, ACE_Null_Mutex> PTimer;
+
+#endif /*TIMER_DISPATCHER_H*/
+
diff --git a/examples/APG/Timers/Task.cpp b/examples/APG/Timers/Task.cpp
new file mode 100644
index 00000000000..8b338df69c4
--- /dev/null
+++ b/examples/APG/Timers/Task.cpp
@@ -0,0 +1,69 @@
+// $Id$
+
+// Listing 1 code/ch20
+#include "ace/Timer_Queue_Adapters.h"
+#include "ace/Timer_Heap.h"
+
+typedef ACE_Thread_Timer_Queue_Adapter<ACE_Timer_Heap>
+ ActiveTimer;
+
+// Listing 1
+// Listing 2 code/ch20
+class CB : public ACE_Event_Handler
+{
+public:
+ CB (int id) : id_(id) { }
+
+ virtual int handle_timeout (const ACE_Time_Value &tv,
+ const void *arg)
+ {
+ ACE_TRACE (ACE_TEXT ("CB::handle_timeout"));
+
+ const int *val = ACE_static_cast (const int*, arg);
+ ACE_ASSERT((*val) == id_);
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Expiry handled by thread %t\n")));
+ return 0;
+ }
+
+private:
+ int id_;
+};
+// Listing 2
+
+// Listing 3 code/ch20
+int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("the main thread %t has started \n")));
+
+ // Create an "active" timer and start its thread.
+ ActiveTimer atimer;
+ atimer.activate ();
+
+ CB cb1 (1);
+ CB cb2 (2);
+ int arg1 = 1;
+ int arg2 = 2;
+
+ // Schedule timers to go off 3 & 4 seconds from now
+ // and then with an interval of 1.1 seconds.
+ const ACE_Time_Value curr_tv = ACE_OS::gettimeofday ();
+ ACE_Time_Value interval = ACE_Time_Value (1, 1000);
+
+ long tid1 = atimer.schedule (&cb1,
+ &arg1,
+ curr_tv + ACE_Time_Value (3L),
+ interval);
+ long tid2 = atimer.schedule (&cb2,
+ &arg2,
+ curr_tv + ACE_Time_Value (4L),
+ interval);
+
+ ACE_Thread_Manager::instance ()->wait (); // Wait forever.
+
+ return 0;
+}
+// Listing 3
+
+
diff --git a/examples/APG/Timers/TimerDispatcher.cpp b/examples/APG/Timers/TimerDispatcher.cpp
new file mode 100644
index 00000000000..1d5bf5a77ba
--- /dev/null
+++ b/examples/APG/Timers/TimerDispatcher.cpp
@@ -0,0 +1,68 @@
+// $Id$
+
+#include "TimerDispatcher.h"
+// Listing 1 code/ch20
+void Timer_Dispatcher::wait_for_event (void)
+{
+ ACE_TRACE (ACE_TEXT ("Timer_Dispatcher::wait_for_event"));
+
+ while (1)
+ {
+ ACE_Time_Value max_tv = timer_queue_->gettimeofday ();
+
+ ACE_Time_Value *this_timeout =
+ this->timer_queue_->calculate_timeout (&max_tv);
+
+ if (*this_timeout == ACE_Time_Value::zero)
+ this->timer_queue_->expire ();
+ else
+ {
+ // Convert to absolute time.
+ ACE_Time_Value next_timeout =
+ timer_queue_->gettimeofday ();
+ next_timeout += *this_timeout;
+ if (this->timer_.wait (&next_timeout) == -1 )
+ this->timer_queue_->expire ();
+ }
+ }
+}
+// Listing 1
+// Listing 2 code/ch20
+long
+Timer_Dispatcher::schedule (ACE_Event_Handler *cb,
+ void *arg,
+ const ACE_Time_Value &abs_time,
+ const ACE_Time_Value &interval)
+{
+ ACE_TRACE (ACE_TEXT ("Timer_Dispatcher::schedule_timer"));
+
+ return this->timer_queue_->schedule
+ (cb, arg, abs_time, interval);
+}
+// Listing 2
+// Listing 3 code/ch20
+int
+Timer_Dispatcher::cancel (ACE_Event_Handler *cb,
+ int dont_call_handle_close)
+{
+ ACE_TRACE (ACE_TEXT ("Timer_Dispatcher::cancel"));
+ return timer_queue_->cancel (cb, dont_call_handle_close);
+}
+// Listing 3
+// Listing 4 code/ch20
+void Timer_Dispatcher::set (ACE_Timer_Queue *timer_queue)
+{
+ ACE_TRACE (ACE_TEXT ("Timer_Dispatcher::set"));
+
+ timer_queue_ = timer_queue;
+}
+// Listing 4
+
+int
+Timer_Dispatcher::reset_interval (long timer_id,
+ const ACE_Time_Value &interval)
+{
+ ACE_TRACE (ACE_TEXT ("Timer_Dispatcher::reset_interval"));
+
+ return timer_queue_->reset_interval(timer_id, interval);
+}
diff --git a/examples/APG/Timers/TimerDispatcher.h b/examples/APG/Timers/TimerDispatcher.h
new file mode 100644
index 00000000000..fc519b77615
--- /dev/null
+++ b/examples/APG/Timers/TimerDispatcher.h
@@ -0,0 +1,40 @@
+/* -*- C++ -*- */
+// $Id$
+
+#if !defined(TIMER_DISPATCHER_H)
+#define TIMER_DISPATCHER_H
+
+#include "ace/Event_Handler.h"
+#include "ace/Singleton.h"
+#include "ace/Synch.h" // needed for ACE_Event
+#include "ace/Timer_Queue.h"
+
+// Listing 1 code/ch20
+class Timer_Dispatcher
+{
+public:
+ void wait_for_event (void);
+
+ long schedule (ACE_Event_Handler *cb,
+ void *arg,
+ const ACE_Time_Value &abs_time,
+ const ACE_Time_Value &interval);
+
+ int cancel (ACE_Event_Handler *cb,
+ int dont_call_handle_close = 1);
+
+ int reset_interval (long timer_id,
+ const ACE_Time_Value &interval);
+
+ void set (ACE_Timer_Queue *timer_queue);
+
+private:
+ ACE_Timer_Queue *timer_queue_;
+ ACE_Event timer_;
+};
+
+typedef ACE_Singleton<Timer_Dispatcher, ACE_Null_Mutex> Timer;
+// Listing 1
+
+#endif /*TIMER_DISPATCHER_H*/
+
diff --git a/examples/APG/Timers/Timers.cpp b/examples/APG/Timers/Timers.cpp
new file mode 100644
index 00000000000..fc5a21e596e
--- /dev/null
+++ b/examples/APG/Timers/Timers.cpp
@@ -0,0 +1,57 @@
+// $Id$
+
+// Listing 1 code/ch20
+#include "ace/Timer_Queue.h"
+#include "ace/Timer_Heap.h"
+#include "ace/Timer_Wheel.h"
+#include "ace/Timer_Hash.h"
+#include "ace/Timer_List.h"
+
+#include "CB.h"
+#include "TimerDispatcher.h"
+
+int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Timer_Queue *timer_queue;
+
+#if defined(HEAP)
+
+ ACE_NEW_RETURN (timer_queue, ACE_Timer_Heap, -1);
+#elsif defined(HASH)
+
+ ACE_NEW_RETURN (timer_queue, ACE_Timer_Hash, -1);
+#elsif defined(WHEEL)
+
+ ACE_NEW_RETURN (timer_queue, ACE_Timer_Wheel, -1);
+#else
+
+ ACE_NEW_RETURN (timer_queue, ACE_Timer_List, -1);
+#endif
+
+ // setup the timer queue
+ Timer::instance ()->set (timer_queue);
+
+ CB cb[10];
+ long args[10];
+ for (int i = 0; i < 10 ; i++)
+ {
+ long timerID =
+ Timer::instance ()->schedule
+ (&cb[i],
+ &args[i],
+ timer_queue->gettimeofday () + (ACE_Time_Value)5,
+ i);
+
+ // Set the timerID state variable of the handler.
+ cb[i].setID (timerID);
+
+ // Implicitly send the handler it's timer id.
+ args[i] = timerID;
+ }
+
+ // "run" the timer.
+ Timer::instance ()->wait_for_event ();
+
+ return 0;
+}
+// Listing 1
diff --git a/examples/APG/Timers/Upcall.cpp b/examples/APG/Timers/Upcall.cpp
new file mode 100644
index 00000000000..1a3294cf5a9
--- /dev/null
+++ b/examples/APG/Timers/Upcall.cpp
@@ -0,0 +1,75 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "Upcall.h"
+#include "PTimerDispatcher.h"
+
+// Listing 2 code/ch20
+int
+UpcallHandler::timeout (PTimerQueue &timer_queue,
+ PCB *handler,
+ const void *arg,
+ const ACE_Time_Value &cur_time)
+{
+ ACE_TRACE (ACE_TEXT ("UpcallHandler::timeout"));
+
+ return (*handler).handleEvent (arg);
+}
+
+int
+UpcallHandler::cancellation (PTimerQueue &timer_queue,
+ PCB *handler)
+{
+ ACE_TRACE (ACE_TEXT ("UpcallHandler::cancellation"));
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Handler %d has been cancelled\n"),
+ handler->getID ()));
+
+ return handler->handleCancel ();
+}
+
+// This method is called when the timer is canceled
+int
+UpcallHandler::deletion (PTimerQueue &timer_queue,
+ PCB *handler,
+ const void *arg)
+{
+ ACE_TRACE (ACE_TEXT ("UpcallHandler::deletion"));
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Handler %d has been deleted\n"),
+ handler->getID ()));
+
+ return handler->handleClose ();
+}
+// Listing 2
+
+
+// Listing 3 code/ch20
+int ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ PCB cb1, cb2;
+ cb1.setID (1);
+ cb2.setID (2);
+ int arg1 = 1, arg2 = 2;
+
+ PTimerQueue *timerQueue;
+
+ ACE_NEW_RETURN (timerQueue, PTimerHeap (), -1);
+
+ PTimer::instance ()->set (timerQueue);
+
+ ACE_Time_Value tv = ACE_OS::gettimeofday ();
+ tv += 20L;
+
+ // Schedule two different timers to go off.
+ PTimer::instance ()->schedule (&cb1, &arg1, tv, 1);
+ PTimer::instance ()->schedule (&cb2, &arg2, tv, 2);
+
+ // Run the timer event loop forever.
+ PTimer::instance ()->wait_for_event ();
+
+ return 0;
+}
+// Listing 3
diff --git a/examples/APG/Timers/Upcall.h b/examples/APG/Timers/Upcall.h
new file mode 100644
index 00000000000..e14532afb3b
--- /dev/null
+++ b/examples/APG/Timers/Upcall.h
@@ -0,0 +1,44 @@
+/* -*- C++ -*- */
+// $Id$
+
+#if !defined(UPCALL_H)
+#define UPCALL_H
+
+#include "ace/Timer_Queue_T.h"
+#include "ace/Timer_Heap_T.h"
+#include "ace/Synch.h"
+
+#include "PCB.h"
+
+// Listing 1 code/ch20
+class UpcallHandler;
+
+typedef ACE_Timer_Queue_T<PCB*, UpcallHandler, ACE_Null_Mutex>
+ PTimerQueue;
+
+// Create a special heap-based timer queue that allows you to
+// control exactly how timer evetns are handled.
+typedef ACE_Timer_Heap_T<PCB*, UpcallHandler, ACE_Null_Mutex>
+ PTimerHeap;
+// Listing 1
+
+class UpcallHandler
+{
+public:
+ int timeout (PTimerQueue &timer_queue,
+ PCB *handler,
+ const void *arg,
+ const ACE_Time_Value &cur_time);
+
+ // This method is called when the timer is canceled.
+ int cancellation (PTimerQueue &timer_queue,
+ PCB *handler);
+
+ // This method is called when the timer queue is destroyed and
+ // the timer is still contained in it.
+ int deletion (PTimerQueue &timer_queue,
+ PCB *handler,
+ const void *arg);
+};
+
+#endif /*UPCALL_H*/
diff --git a/examples/APG/Timers/timers.mpc b/examples/APG/Timers/timers.mpc
new file mode 100644
index 00000000000..3dc5724b752
--- /dev/null
+++ b/examples/APG/Timers/timers.mpc
@@ -0,0 +1,31 @@
+project(Alarm) : aceexe {
+ exename = Alarm
+ Source_Files {
+ Alarm.cpp
+ }
+}
+
+project(Task) : aceexe {
+ exename = Task
+ Source_Files {
+ Task.cpp
+ }
+}
+
+project(Timers) : aceexe {
+ exename = Timers
+ Source_Files {
+ Timers.cpp
+ CB.cpp
+ TimerDispatcher.cpp
+ }
+}
+
+project(Upcall) : aceexe {
+ exename = Upcall
+ Source_Files {
+ Upcall.cpp
+ PCB.cpp
+ PTimerDispatcher.cpp
+ }
+}
diff --git a/examples/APG/Timers/timers.mwc b/examples/APG/Timers/timers.mwc
new file mode 100644
index 00000000000..b3032dea82d
--- /dev/null
+++ b/examples/APG/Timers/timers.mwc
@@ -0,0 +1,3 @@
+workspace {
+ timers.mpc
+}