]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/mplexer.hh
update version
[thirdparty/pdns.git] / pdns / mplexer.hh
CommitLineData
ab3e8a6c
BH
1#include <boost/function.hpp>
2#include <boost/any.hpp>
a1dfcec8 3#include <boost/shared_array.hpp>
0bff046b
BH
4#include <boost/tuple/tuple.hpp>
5#include <boost/tuple/tuple_comparison.hpp>
6#include <vector>
ab3e8a6c
BH
7#include <map>
8#include <stdexcept>
9#include <string>
10
11class FDMultiplexerException : public std::runtime_error
12{
13public:
14 FDMultiplexerException(const std::string& str) : std::runtime_error(str)
15 {}
16};
17
a1dfcec8
BH
18
19/** Very simple FD multiplexer, based on callbacks and boost::any parameters
20 As a special service, this parameter is kept around and can be modified,
21 allowing for state to be stored inside the multiplexer.
22
23 It has some "interesting" semantics
24*/
1f4abb20 25
ab3e8a6c
BH
26class FDMultiplexer
27{
28protected:
29 typedef boost::function< void(int, boost::any&) > callbackfunc_t;
30 struct Callback
31 {
32 callbackfunc_t d_callback;
33 boost::any d_parameter;
0bff046b 34 struct timeval d_ttd;
ab3e8a6c
BH
35 };
36
37public:
38 FDMultiplexer() : d_inrun(false)
39 {}
40 virtual ~FDMultiplexer()
41 {}
42
0bff046b 43 virtual int run(struct timeval* tv) = 0;
ab3e8a6c 44
a1dfcec8 45 //! Add an fd to the read watch list - currently an fd can only be on one list at a time!
ab3e8a6c
BH
46 virtual void addReadFD(int fd, callbackfunc_t toDo, boost::any parameter=boost::any())
47 {
a1dfcec8 48 this->addFD(d_readCallbacks, fd, toDo, parameter);
ab3e8a6c
BH
49 }
50
a1dfcec8 51 //! Add an fd to the write watch list - currently an fd can only be on one list at a time!
ab3e8a6c
BH
52 virtual void addWriteFD(int fd, callbackfunc_t toDo, boost::any parameter=boost::any())
53 {
a1dfcec8 54 this->addFD(d_writeCallbacks, fd, toDo, parameter);
ab3e8a6c
BH
55 }
56
a1dfcec8 57 //! Remove an fd from the read watch list. You can't call this function on an fd that is closed already!
6dcd28c3 58 /** WARNING: references to 'parameter' become invalid after this function! */
ab3e8a6c
BH
59 virtual void removeReadFD(int fd)
60 {
a1dfcec8 61 this->removeFD(d_readCallbacks, fd);
ab3e8a6c
BH
62 }
63
a1dfcec8 64 //! Remove an fd from the write watch list. You can't call this function on an fd that is closed already!
6dcd28c3 65 /** WARNING: references to 'parameter' become invalid after this function! */
a1dfcec8 66 virtual void removeWriteFD(int fd)
ab3e8a6c 67 {
a1dfcec8 68 this->removeFD(d_writeCallbacks, fd);
ab3e8a6c
BH
69 }
70
0bff046b
BH
71 virtual void setReadTTD(int fd, struct timeval tv, int timeout)
72 {
73 if(!d_readCallbacks.count(fd))
74 throw FDMultiplexerException("attempt to timestamp fd not in the multiplexer");
75 tv.tv_sec += timeout;
76 d_readCallbacks[fd].d_ttd=tv;
77 }
78
79 virtual std::vector<std::pair<int, boost::any> > getTimeouts(const struct timeval& tv)
80 {
81 std::vector<std::pair<int, boost::any> > ret;
82 for(callbackmap_t::iterator i=d_readCallbacks.begin(); i!=d_readCallbacks.end(); ++i)
83 if(i->second.d_ttd.tv_sec && boost::tie(tv.tv_sec, tv.tv_usec) > boost::tie(i->second.d_ttd.tv_sec, i->second.d_ttd.tv_usec))
84 ret.push_back(std::make_pair(i->first, i->second.d_parameter));
85 return ret;
86 }
87
1f4abb20
BH
88 typedef FDMultiplexer* getMultiplexer_t();
89 typedef std::multimap<int, getMultiplexer_t*> FDMultiplexermap_t;
90
91 static FDMultiplexermap_t& getMultiplexerMap()
92 {
93 static FDMultiplexermap_t theMap;
94 return theMap;
95 }
96
97 virtual std::string getName() = 0;
98
ab3e8a6c
BH
99protected:
100 typedef std::map<int, Callback> callbackmap_t;
101 callbackmap_t d_readCallbacks, d_writeCallbacks;
ab3e8a6c
BH
102
103 virtual void addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, boost::any parameter)=0;
104 virtual void removeFD(callbackmap_t& cbmap, int fd)=0;
105 bool d_inrun;
a1dfcec8 106 callbackmap_t::iterator d_iter;
1f4abb20
BH
107};
108
109class SelectFDMultiplexer : public FDMultiplexer
110{
111public:
112 SelectFDMultiplexer()
113 {}
114 virtual ~SelectFDMultiplexer()
115 {}
ab3e8a6c 116
0bff046b 117 virtual int run(struct timeval* tv);
1f4abb20
BH
118
119 virtual void addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, boost::any parameter);
120 virtual void removeFD(callbackmap_t& cbmap, int fd);
121 std::string getName()
122 {
123 return "select";
124 }
ab3e8a6c
BH
125};
126