00001 /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ 00002 /* 00003 * timer-handler.h 00004 * Copyright (C) 1997 by USC/ISI 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms are permitted 00008 * provided that the above copyright notice and this paragraph are 00009 * duplicated in all such forms and that any documentation, advertising 00010 * materials, and other materials related to such distribution and use 00011 * acknowledge that the software was developed by the University of 00012 * Southern California, Information Sciences Institute. The name of the 00013 * University may not be used to endorse or promote products derived from 00014 * this software without specific prior written permission. 00015 * 00016 * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED 00017 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 00018 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00019 * 00020 * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/common/timer-handler.h,v 1.8 2000/11/02 22:46:37 johnh Exp $ (USC/ISI) 00021 */ 00022 00023 #ifndef timer_handler_h 00024 #define timer_handler_h 00025 00026 #include "scheduler.h" 00027 00028 /* 00029 * Abstract base class to deal with timer-style handlers. 00030 * 00031 * 00032 * To define a new timer, subclass this function and define handle: 00033 * 00034 * class MyTimer : public TimerHandler { 00035 * public: 00036 * MyTimer(MyAgentClass *a) : AgentTimerHandler() { a_ = a; } 00037 * virtual double expire(Event *e); 00038 * protected: 00039 * MyAgentClass *a_; 00040 * }; 00041 * 00042 * Then define expire. 00043 * 00044 * Often MyTimer will be a friend of MyAgentClass, 00045 * or expire() will only call a function of MyAgentClass. 00046 * 00047 * See tcp-rbp.{cc,h} for a real example. 00048 */ 00049 #define TIMER_HANDLED -1.0 // xxx: should be const double in class? 00050 00051 class TimerHandler : public Handler { 00052 public: 00053 TimerHandler() : status_(TIMER_IDLE) { } 00054 00055 void sched(double delay); // cannot be pending 00056 void resched(double delay); // may or may not be pending 00057 // if you don't know the pending status 00058 // call resched() 00059 void cancel(); // must be pending 00060 inline void force_cancel() { // cancel! 00061 if (status_ == TIMER_PENDING) { 00062 _cancel(); 00063 status_ = TIMER_IDLE; 00064 } 00065 } 00066 enum TimerStatus { TIMER_IDLE, TIMER_PENDING, TIMER_HANDLING }; 00067 int status() { return status_; }; 00068 00069 protected: 00070 virtual void expire(Event *) = 0; // must be filled in by client 00071 // Should call resched() if it wants to reschedule the interface. 00072 00073 virtual void handle(Event *); 00074 int status_; 00075 Event event_; 00076 00077 private: 00078 inline void _sched(double delay) { 00079 (void)Scheduler::instance().schedule(this, &event_, delay); 00080 } 00081 inline void _cancel() { 00082 (void)Scheduler::instance().cancel(&event_); 00083 // no need to free event_ since it's statically allocated 00084 } 00085 }; 00086 00087 // Local Variables: 00088 // mode:c++ 00089 // End: 00090 00091 #endif /* timer_handler_h */
1.3.3