]>
Commit | Line | Data |
---|---|---|
ab3e8a6c BH |
1 | #include <boost/function.hpp> |
2 | #include <boost/any.hpp> | |
a1dfcec8 | 3 | #include <boost/shared_array.hpp> |
ab3e8a6c BH |
4 | #include <map> |
5 | #include <stdexcept> | |
6 | #include <string> | |
7 | ||
8 | class FDMultiplexerException : public std::runtime_error | |
9 | { | |
10 | public: | |
11 | FDMultiplexerException(const std::string& str) : std::runtime_error(str) | |
12 | {} | |
13 | }; | |
14 | ||
a1dfcec8 BH |
15 | |
16 | /** Very simple FD multiplexer, based on callbacks and boost::any parameters | |
17 | As a special service, this parameter is kept around and can be modified, | |
18 | allowing for state to be stored inside the multiplexer. | |
19 | ||
20 | It has some "interesting" semantics | |
21 | */ | |
1f4abb20 | 22 | |
ab3e8a6c BH |
23 | class FDMultiplexer |
24 | { | |
25 | protected: | |
26 | typedef boost::function< void(int, boost::any&) > callbackfunc_t; | |
27 | struct Callback | |
28 | { | |
29 | callbackfunc_t d_callback; | |
30 | boost::any d_parameter; | |
31 | }; | |
32 | ||
33 | public: | |
34 | FDMultiplexer() : d_inrun(false) | |
35 | {} | |
36 | virtual ~FDMultiplexer() | |
37 | {} | |
38 | ||
39 | virtual int run(struct timeval* tv=0) = 0; | |
40 | ||
a1dfcec8 | 41 | //! Add an fd to the read watch list - currently an fd can only be on one list at a time! |
ab3e8a6c BH |
42 | virtual void addReadFD(int fd, callbackfunc_t toDo, boost::any parameter=boost::any()) |
43 | { | |
a1dfcec8 | 44 | this->addFD(d_readCallbacks, fd, toDo, parameter); |
ab3e8a6c BH |
45 | } |
46 | ||
a1dfcec8 | 47 | //! Add an fd to the write watch list - currently an fd can only be on one list at a time! |
ab3e8a6c BH |
48 | virtual void addWriteFD(int fd, callbackfunc_t toDo, boost::any parameter=boost::any()) |
49 | { | |
a1dfcec8 | 50 | this->addFD(d_writeCallbacks, fd, toDo, parameter); |
ab3e8a6c BH |
51 | } |
52 | ||
a1dfcec8 | 53 | //! Remove an fd from the read watch list. You can't call this function on an fd that is closed already! |
6dcd28c3 | 54 | /** WARNING: references to 'parameter' become invalid after this function! */ |
ab3e8a6c BH |
55 | virtual void removeReadFD(int fd) |
56 | { | |
a1dfcec8 | 57 | this->removeFD(d_readCallbacks, fd); |
ab3e8a6c BH |
58 | } |
59 | ||
a1dfcec8 | 60 | //! Remove an fd from the write watch list. You can't call this function on an fd that is closed already! |
6dcd28c3 | 61 | /** WARNING: references to 'parameter' become invalid after this function! */ |
a1dfcec8 | 62 | virtual void removeWriteFD(int fd) |
ab3e8a6c | 63 | { |
a1dfcec8 | 64 | this->removeFD(d_writeCallbacks, fd); |
ab3e8a6c BH |
65 | } |
66 | ||
1f4abb20 BH |
67 | typedef FDMultiplexer* getMultiplexer_t(); |
68 | typedef std::multimap<int, getMultiplexer_t*> FDMultiplexermap_t; | |
69 | ||
70 | static FDMultiplexermap_t& getMultiplexerMap() | |
71 | { | |
72 | static FDMultiplexermap_t theMap; | |
73 | return theMap; | |
74 | } | |
75 | ||
76 | virtual std::string getName() = 0; | |
77 | ||
ab3e8a6c BH |
78 | protected: |
79 | typedef std::map<int, Callback> callbackmap_t; | |
80 | callbackmap_t d_readCallbacks, d_writeCallbacks; | |
ab3e8a6c BH |
81 | |
82 | virtual void addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, boost::any parameter)=0; | |
83 | virtual void removeFD(callbackmap_t& cbmap, int fd)=0; | |
84 | bool d_inrun; | |
a1dfcec8 | 85 | callbackmap_t::iterator d_iter; |
1f4abb20 BH |
86 | }; |
87 | ||
88 | class SelectFDMultiplexer : public FDMultiplexer | |
89 | { | |
90 | public: | |
91 | SelectFDMultiplexer() | |
92 | {} | |
93 | virtual ~SelectFDMultiplexer() | |
94 | {} | |
ab3e8a6c | 95 | |
1f4abb20 BH |
96 | virtual int run(struct timeval* tv=0); |
97 | ||
98 | virtual void addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, boost::any parameter); | |
99 | virtual void removeFD(callbackmap_t& cbmap, int fd); | |
100 | std::string getName() | |
101 | { | |
102 | return "select"; | |
103 | } | |
ab3e8a6c BH |
104 | }; |
105 |