]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/pollmplexer.cc
9 #include "namespaces.hh"
11 FDMultiplexer
* FDMultiplexer::getMultiplexerSilent()
13 FDMultiplexer
* ret
= nullptr;
14 for(const auto& i
: FDMultiplexer::getMultiplexerMap()) {
19 catch(const FDMultiplexerException
& fe
) {
28 class PollFDMultiplexer
: public FDMultiplexer
33 virtual ~PollFDMultiplexer()
37 virtual int run(struct timeval
* tv
, int timeout
=500);
39 virtual void addFD(callbackmap_t
& cbmap
, int fd
, callbackfunc_t toDo
, const funcparam_t
& parameter
);
40 virtual void removeFD(callbackmap_t
& cbmap
, int fd
);
48 static FDMultiplexer
* make()
50 return new PollFDMultiplexer();
53 static struct RegisterOurselves
56 FDMultiplexer::getMultiplexerMap().insert(make_pair(1, &make
));
60 void PollFDMultiplexer::addFD(callbackmap_t
& cbmap
, int fd
, callbackfunc_t toDo
, const boost::any
& parameter
)
64 cb
.d_parameter
=parameter
;
65 memset(&cb
.d_ttd
, 0, sizeof(cb
.d_ttd
));
67 throw FDMultiplexerException("Tried to add fd "+std::to_string(fd
)+ " to multiplexer twice");
71 void PollFDMultiplexer::removeFD(callbackmap_t
& cbmap
, int fd
)
73 if(d_inrun
&& d_iter
->first
==fd
) // trying to remove us!
77 throw FDMultiplexerException("Tried to remove unlisted fd "+std::to_string(fd
)+ " from multiplexer");
80 bool pollfdcomp(const struct pollfd
& a
, const struct pollfd
& b
)
85 int PollFDMultiplexer::run(struct timeval
* now
, int timeout
)
88 throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!\n");
91 vector
<struct pollfd
> pollfds
;
94 for(callbackmap_t::const_iterator i
=d_readCallbacks
.begin(); i
!= d_readCallbacks
.end(); ++i
) {
96 pollfd
.events
= POLLIN
;
97 pollfds
.push_back(pollfd
);
100 for(callbackmap_t::const_iterator i
=d_writeCallbacks
.begin(); i
!= d_writeCallbacks
.end(); ++i
) {
101 pollfd
.fd
= i
->first
;
102 pollfd
.events
= POLLOUT
;
103 pollfds
.push_back(pollfd
);
106 int ret
=poll(&pollfds
[0], pollfds
.size(), timeout
);
107 gettimeofday(now
, 0); // MANDATORY!
109 if(ret
< 0 && errno
!=EINTR
)
110 throw FDMultiplexerException("poll returned error: "+stringerror());
112 d_iter
=d_readCallbacks
.end();
115 for(unsigned int n
= 0; n
< pollfds
.size(); ++n
) {
116 if(pollfds
[n
].revents
== POLLIN
) {
117 d_iter
=d_readCallbacks
.find(pollfds
[n
].fd
);
119 if(d_iter
!= d_readCallbacks
.end()) {
120 d_iter
->second
.d_callback(d_iter
->first
, d_iter
->second
.d_parameter
);
121 continue; // so we don't refind ourselves as writable!
124 else if(pollfds
[n
].revents
== POLLOUT
) {
125 d_iter
=d_writeCallbacks
.find(pollfds
[n
].fd
);
127 if(d_iter
!= d_writeCallbacks
.end()) {
128 d_iter
->second
.d_callback(d_iter
->first
, d_iter
->second
.d_parameter
);
138 void acceptData(int fd
, boost::any
& parameter
)
140 cout
<<"Have data on fd "<<fd
<<endl
;
141 Socket
* sock
=boost::any_cast
<Socket
*>(parameter
);
144 sock
->recvFrom(packet
, rem
);
145 cout
<<"Received "<<packet
.size()<<" bytes!\n";
151 Socket
s(AF_INET
, SOCK_DGRAM
);
153 IPEndpoint
loc("0.0.0.0", 2000);
156 PollFDMultiplexer sfm
;
158 sfm
.addReadFD(s
.getHandle(), &acceptData
, &s
);
160 for(int n
=0; n
< 100 ; ++n
) {
163 sfm
.removeReadFD(s
.getHandle());
164 sfm
.removeReadFD(s
.getHandle());