]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/pollmplexer.cc
9 #include "namespaces.hh"
12 static FDMultiplexer
* make()
14 return new PollFDMultiplexer();
17 static struct RegisterOurselves
20 FDMultiplexer::getMultiplexerMap().insert(make_pair(1, &make
));
24 void PollFDMultiplexer::addFD(callbackmap_t
& cbmap
, int fd
, callbackfunc_t toDo
, const boost::any
& parameter
)
28 cb
.d_parameter
=parameter
;
29 memset(&cb
.d_ttd
, 0, sizeof(cb
.d_ttd
));
31 throw FDMultiplexerException("Tried to add fd "+std::to_string(fd
)+ " to multiplexer twice");
35 void PollFDMultiplexer::removeFD(callbackmap_t
& cbmap
, int fd
)
37 if(d_inrun
&& d_iter
->first
==fd
) // trying to remove us!
41 throw FDMultiplexerException("Tried to remove unlisted fd "+std::to_string(fd
)+ " from multiplexer");
44 bool pollfdcomp(const struct pollfd
& a
, const struct pollfd
& b
)
49 int PollFDMultiplexer::run(struct timeval
* now
, int timeout
=500)
52 throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!\n");
55 vector
<struct pollfd
> pollfds
;
58 for(callbackmap_t::const_iterator i
=d_readCallbacks
.begin(); i
!= d_readCallbacks
.end(); ++i
) {
60 pollfd
.events
= POLLIN
;
61 pollfds
.push_back(pollfd
);
64 for(callbackmap_t::const_iterator i
=d_writeCallbacks
.begin(); i
!= d_writeCallbacks
.end(); ++i
) {
66 pollfd
.events
= POLLOUT
;
67 pollfds
.push_back(pollfd
);
70 int ret
=poll(&pollfds
[0], pollfds
.size(), timeout
);
71 gettimeofday(now
, 0); // MANDATORY!
73 if(ret
< 0 && errno
!=EINTR
)
74 throw FDMultiplexerException("poll returned error: "+stringerror());
76 d_iter
=d_readCallbacks
.end();
79 for(unsigned int n
= 0; n
< pollfds
.size(); ++n
) {
80 if(pollfds
[n
].revents
== POLLIN
) {
81 d_iter
=d_readCallbacks
.find(pollfds
[n
].fd
);
83 if(d_iter
!= d_readCallbacks
.end()) {
84 d_iter
->second
.d_callback(d_iter
->first
, d_iter
->second
.d_parameter
);
85 continue; // so we don't refind ourselves as writable!
88 else if(pollfds
[n
].revents
== POLLOUT
) {
89 d_iter
=d_writeCallbacks
.find(pollfds
[n
].fd
);
91 if(d_iter
!= d_writeCallbacks
.end()) {
92 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 PollFDMultiplexer 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());