]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/selectmplexer.cc
9 #include "namespaces.hh"
11 static FDMultiplexer
* make()
13 return new SelectFDMultiplexer();
16 static struct RegisterOurselves
19 FDMultiplexer::getMultiplexerMap().insert(make_pair(1, &make
));
23 void SelectFDMultiplexer::addFD(callbackmap_t
& cbmap
, int fd
, callbackfunc_t toDo
, const boost::any
& parameter
)
27 cb
.d_parameter
=parameter
;
28 memset(&cb
.d_ttd
, 0, sizeof(cb
.d_ttd
));
30 throw FDMultiplexerException("Tried to add fd "+std::to_string(fd
)+ " to multiplexer twice");
34 void SelectFDMultiplexer::removeFD(callbackmap_t
& cbmap
, int fd
)
36 if(d_inrun
&& d_iter
->first
==fd
) // trying to remove us!
40 throw FDMultiplexerException("Tried to remove unlisted fd "+std::to_string(fd
)+ " from multiplexer");
43 int SelectFDMultiplexer::run(struct timeval
* now
, int timeout
)
46 throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!\n");
48 fd_set readfds
, writefds
;
54 for(callbackmap_t::const_iterator i
=d_readCallbacks
.begin(); i
!= d_readCallbacks
.end(); ++i
) {
55 FD_SET(i
->first
, &readfds
);
56 fdmax
=max(i
->first
, fdmax
);
59 for(callbackmap_t::const_iterator i
=d_writeCallbacks
.begin(); i
!= d_writeCallbacks
.end(); ++i
) {
60 FD_SET(i
->first
, &writefds
);
61 fdmax
=max(i
->first
, fdmax
);
64 struct timeval tv
={timeout
/ 1000 , (timeout
% 1000) * 1000};
65 int ret
=select(fdmax
+ 1, &readfds
, &writefds
, 0, &tv
);
66 gettimeofday(now
, 0); // MANDATORY!
68 if(ret
< 0 && errno
!=EINTR
)
69 throw FDMultiplexerException("select returned error: "+stringerror());
71 if(ret
< 1) // nothing - thanks AB
74 d_iter
=d_readCallbacks
.end();
78 for(callbackmap_t::iterator i
=d_readCallbacks
.begin(); i
!= d_readCallbacks
.end() && i
->first
<= fdmax
; ) {
81 if(FD_ISSET(d_iter
->first
, &readfds
)) {
82 d_iter
->second
.d_callback(d_iter
->first
, d_iter
->second
.d_parameter
);
84 continue; // so we don't refind ourselves as writable
88 for(callbackmap_t::iterator i
=d_writeCallbacks
.begin(); i
!= d_writeCallbacks
.end() && i
->first
<= fdmax
; ) {
90 if(FD_ISSET(d_iter
->first
, &writefds
)) {
91 d_iter
->second
.d_callback(d_iter
->first
, d_iter
->second
.d_parameter
);
102 void acceptData(int fd
, boost::any
& parameter
)
104 cout
<<"Have data on fd "<<fd
<<endl
;
105 Socket
* sock
=boost::any_cast
<Socket
*>(parameter
);
108 sock
->recvFrom(packet
, rem
);
109 cout
<<"Received "<<packet
.size()<<" bytes!\n";
115 Socket
s(AF_INET
, SOCK_DGRAM
);
117 IPEndpoint
loc("0.0.0.0", 2000);
120 SelectFDMultiplexer sfm
;
122 sfm
.addReadFD(s
.getHandle(), &acceptData
, &s
);
124 for(int n
=0; n
< 100 ; ++n
) {
127 sfm
.removeReadFD(s
.getHandle());
128 sfm
.removeReadFD(s
.getHandle());