]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/selectmplexer.cc
8 #include <boost/lexical_cast.hpp>
13 #include "namespaces.hh"
14 #include "namespaces.hh"
16 static FDMultiplexer
* make()
18 return new SelectFDMultiplexer();
21 static struct RegisterOurselves
24 FDMultiplexer::getMultiplexerMap().insert(make_pair(1, &make
));
28 void SelectFDMultiplexer::addFD(callbackmap_t
& cbmap
, int fd
, callbackfunc_t toDo
, const boost::any
& parameter
)
32 cb
.d_parameter
=parameter
;
33 memset(&cb
.d_ttd
, 0, sizeof(cb
.d_ttd
));
35 throw FDMultiplexerException("Tried to add fd "+lexical_cast
<string
>(fd
)+ " to multiplexer twice");
39 void SelectFDMultiplexer::removeFD(callbackmap_t
& cbmap
, int fd
)
41 if(d_inrun
&& d_iter
->first
==fd
) // trying to remove us!
45 throw FDMultiplexerException("Tried to remove unlisted fd "+lexical_cast
<string
>(fd
)+ " from multiplexer");
48 int SelectFDMultiplexer::run(struct timeval
* now
)
51 throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!\n");
53 fd_set readfds
, writefds
;
59 for(callbackmap_t::const_iterator i
=d_readCallbacks
.begin(); i
!= d_readCallbacks
.end(); ++i
) {
60 FD_SET(i
->first
, &readfds
);
61 fdmax
=max(i
->first
, fdmax
);
64 for(callbackmap_t::const_iterator i
=d_writeCallbacks
.begin(); i
!= d_writeCallbacks
.end(); ++i
) {
65 FD_SET(i
->first
, &writefds
);
66 fdmax
=max(i
->first
, fdmax
);
69 struct timeval tv
={0,500000};
70 int ret
=select(fdmax
+ 1, &readfds
, &writefds
, 0, &tv
);
71 Utility::gettimeofday(now
, 0); // MANDATORY!
73 if(ret
< 0 && errno
!=EINTR
)
74 throw FDMultiplexerException("select returned error: "+stringerror());
76 if(ret
< 1) // nothing - thanks AB
79 d_iter
=d_readCallbacks
.end();
82 for(callbackmap_t::iterator i
=d_readCallbacks
.begin(); i
!= d_readCallbacks
.end() && i
->first
<= fdmax
; ) {
85 if(FD_ISSET(d_iter
->first
, &readfds
)) {
86 d_iter
->second
.d_callback(d_iter
->first
, d_iter
->second
.d_parameter
);
87 continue; // so we don't refind ourselves as writable
91 for(callbackmap_t::iterator i
=d_writeCallbacks
.begin(); i
!= d_writeCallbacks
.end() && i
->first
<= fdmax
; ) {
93 if(FD_ISSET(d_iter
->first
, &writefds
)) {
94 d_iter
->second
.d_callback(d_iter
->first
, d_iter
->second
.d_parameter
);
104 void acceptData(int fd
, boost::any
& parameter
)
106 cout
<<"Have data on fd "<<fd
<<endl
;
107 Socket
* sock
=boost::any_cast
<Socket
*>(parameter
);
110 sock
->recvFrom(packet
, rem
);
111 cout
<<"Received "<<packet
.size()<<" bytes!\n";
117 Socket
s(AF_INET
, SOCK_DGRAM
);
119 IPEndpoint
loc("0.0.0.0", 2000);
122 SelectFDMultiplexer sfm
;
124 sfm
.addReadFD(s
.getHandle(), &acceptData
, &s
);
126 for(int n
=0; n
< 100 ; ++n
) {
129 sfm
.removeReadFD(s
.getHandle());
130 sfm
.removeReadFD(s
.getHandle());