File: Timeout.cpp

package info (click to toggle)
eris 1.2.1-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 2,360 kB
  • ctags: 1,348
  • sloc: sh: 8,289; cpp: 7,576; perl: 287; ansic: 172; makefile: 143
file content (126 lines) | stat: -rw-r--r-- 2,843 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#ifdef HAVE_CONFIG_H
	#include "config.h"
#endif

#include <Eris/Timeout.h>

#include <Eris/Poll.h>
#include <Eris/Exceptions.h>

#include <limits.h>

using namespace Time;

// The longest wait time for poll() to return.
// This should be as long as possible, since the
// only reason to limit the wait is due to
// the addition of new timeouts. The timeout sets
// a flag in the poll class if that happens,
// it's the responsibility of the poll to check.
static const unsigned long max_wait = ULONG_MAX;

namespace Eris
{

std::map<Timeout::Label, Timeout*> Timeout::_allTimeouts;
	
////////////////////////////////////////////////////////////////////////////////////////////////#	

Timeout::Timeout(const std::string &label, unsigned long milli) :
	_label(label),
	_fired(false)
{
	TimeoutMap::iterator T = _allTimeouts.find(_label);
	if (T != _allTimeouts.end())
	    throw InvalidOperation("Duplicate label '" + label + "' for timeout");
       
	_allTimeouts.insert(_allTimeouts.begin(),
	    TimeoutMap::value_type(_label, this));
	
	_due = Time::Stamp::now() + milli;

	Poll::newTimeout();
}

Timeout::Timeout(const std::string &label, void* inst, unsigned long milli) :
	_label(label, inst),
	_fired(false)
{
	TimeoutMap::iterator T = _allTimeouts.find(_label);
	if (T != _allTimeouts.end())
	    throw InvalidOperation("Duplicate label '" + label + "' for timeout attached to instace");
       
	_allTimeouts.insert(_allTimeouts.begin(),
	    TimeoutMap::value_type(_label, this));
	
	_due = Time::Stamp::now() + milli;

	Poll::newTimeout();
}

Timeout::~Timeout()
{
	if(!_allTimeouts.erase(_label))
		throw InvalidOperation("Corrupted timeout map - very bad!");
}

/*
Timeout& Timeout::operator=(const Timeout &t)
{
	
}
*/

bool Timeout::isExpired() const
{
	return (_due < Time::Stamp::now());
}

unsigned long Timeout::poll(const Time::Stamp &t)
{
	if (!_fired) {
		long diff = (_due - t).milliseconds();
		if(diff > 0) // not finished yet
			return diff;
		Expired();	// invoke the signal
		_fired = true;
	}

	return max_wait; // Doesn't need to be called again
}

void Timeout::reset(unsigned long milli)
{
	_fired = false;
	_due = Time::Stamp::now() + milli;
}

void Timeout::extend(unsigned long milli)
{
	_due = _due + milli;
}

//////////////////////////////////////////////////////////////////////////////////////

const Timeout* Timeout::findByName(const std::string &nm, void* inst)
{
	TimeoutMap::iterator T = _allTimeouts.find(Label(nm, inst));
	if (T == _allTimeouts.end())
		return NULL;
	return T->second;
}

unsigned long Timeout::pollAll()
{
	Time::Stamp now = Time::Stamp::now();
	unsigned long wait = max_wait;
	for (TimeoutMap::iterator T=_allTimeouts.begin(); T != _allTimeouts.end(); ++T) {
		unsigned long this_wait = T->second->poll(now);
		if(this_wait < wait)
			wait = this_wait;
	}
	return wait;
}


}