[Click] How to implement a Timeout?

Bart Braem bart.braem at ua.ac.be
Sat May 21 08:07:05 EDT 2005


> I have thought in implementing a new class FT. Next, a new class
> FTEntry, and this last class will contain a Timer variable and a
> expire_timer function. So, each entry of the FT will have its own
> timeout and when a new ARPEntry is created, a new Timeout will be created.
> But, when a timeout of an entry expires, it has to delete the entry, so,
> delete itself!
>
> What is the best solution to implement this type of timeout? Any other
> idea?

Here's how I handle those situations in my routing table implementation:
I have a map containing routing entries as structs. Each struct has at least 
some unique identifier (in my case IP adresses), a pointer to the current 
element and a Timer. I then initialise that timer with a static callback 
function in the element and a specific timeout. When the timer expires the 
callback function is called, it searches the right element and there it does 
what needs to be done. If deletion is necessary I can delete the map entries.
Some example code:

in the element header file:

struct routing_table_entry{
	...
	Timer* expiry;
};

typedef HashMap<IPAddress, routing_table_entry> RouteMap;

private:
	struct TimerData{
		ThisElement* me;
		IPAddress * ip;
	};

	static void handleExpiry(Timer*, void *); // calback function for timers
	void expire(const IPAddress &, TimerData *);
	RouteMap routes,

In the cc file:

void ThisElement::insertRoutetableEntry(... const IPAddress & ip){
	struct routing_table_entry data;
	// initialise data
	...

	TimerData* timerdata = new TimerData();
	timerdata->ip = new IPAddress(ip);
	timerdata->me = this;
	data.expiry = new Timer(&ThisElement::handleExpiry,timerdata);
	data.expiry->initialize(this);
	data.expiry->schedule_after_ms(...);
	
	routes.insert(ip,data);
}
void ThisElement::handleExpiry(Timer*, void * data){
	TimerData * timerdata = (TimerData*) data;
	assert(timerdata);
	timerdata->me->expire(*timerdata->ip,timerdata);
}

void ThisElement::expire(const IPAddress & ip, TimerData * timerdata){
	// pass timerdata too to clean up memory after timer expires completely
	RouteMap::Pair* pair = routes.find_pair(ip);
	assert(pair);
	if(pair->...){ // need to reschedule
		pair->value.expiry->schedule_after_ms(AODV_DELETE_PERIOD);
	} else { // delete
		delete(pair->value.expiry);
		routes.remove(ip);
		delete timerdata->ip;
		delete timerdata;
	}
}

If you want more information feel free to contact me.

Bart


More information about the click mailing list