]>
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) override
;
38 virtual void getAvailableFDs(std::vector
<int>& fds
, int timeout
) override
;
40 virtual void addFD(callbackmap_t
& cbmap
, int fd
, callbackfunc_t toDo
, const funcparam_t
& parameter
, const struct timeval
* ttd
=nullptr) override
;
41 virtual void removeFD(callbackmap_t
& cbmap
, int fd
) override
;
43 string
getName() const override
48 vector
<struct pollfd
> preparePollFD() const;
51 static FDMultiplexer
* make()
53 return new PollFDMultiplexer();
56 static struct RegisterOurselves
59 FDMultiplexer::getMultiplexerMap().insert(make_pair(1, &make
));
63 void PollFDMultiplexer::addFD(callbackmap_t
& cbmap
, int fd
, callbackfunc_t toDo
, const boost::any
& parameter
, const struct timeval
* ttd
)
65 accountingAddFD(cbmap
, fd
, toDo
, parameter
, ttd
);
68 void PollFDMultiplexer::removeFD(callbackmap_t
& cbmap
, int fd
)
70 if(d_inrun
&& d_iter
->d_fd
==fd
) // trying to remove us!
74 throw FDMultiplexerException("Tried to remove unlisted fd "+std::to_string(fd
)+ " from multiplexer");
77 vector
<struct pollfd
> PollFDMultiplexer::preparePollFD() const
79 vector
<struct pollfd
> pollfds
;
80 pollfds
.reserve(d_readCallbacks
.size() + d_writeCallbacks
.size());
83 for(const auto& cb
: d_readCallbacks
) {
85 pollfd
.events
= POLLIN
;
86 pollfds
.push_back(pollfd
);
89 for(const auto& cb
: d_writeCallbacks
) {
91 pollfd
.events
= POLLOUT
;
92 pollfds
.push_back(pollfd
);
98 void PollFDMultiplexer::getAvailableFDs(std::vector
<int>& fds
, int timeout
)
100 auto pollfds
= preparePollFD();
101 int ret
= poll(&pollfds
[0], pollfds
.size(), timeout
);
103 if (ret
< 0 && errno
!= EINTR
)
104 throw FDMultiplexerException("poll returned error: " + stringerror());
106 for(const auto& pollfd
: pollfds
) {
107 if (pollfd
.revents
& POLLIN
|| pollfd
.revents
& POLLOUT
) {
108 fds
.push_back(pollfd
.fd
);
113 int PollFDMultiplexer::run(struct timeval
* now
, int timeout
)
116 throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!\n");
119 auto pollfds
= preparePollFD();
121 int ret
=poll(&pollfds
[0], pollfds
.size(), timeout
);
122 gettimeofday(now
, 0); // MANDATORY!
124 if(ret
< 0 && errno
!=EINTR
)
125 throw FDMultiplexerException("poll returned error: "+stringerror());
127 d_iter
=d_readCallbacks
.end();
130 for(const auto& pollfd
: pollfds
) {
131 if(pollfd
.revents
& POLLIN
) {
132 d_iter
=d_readCallbacks
.find(pollfd
.fd
);
134 if(d_iter
!= d_readCallbacks
.end()) {
135 d_iter
->d_callback(d_iter
->d_fd
, d_iter
->d_parameter
);
136 continue; // so we don't refind ourselves as writable!
139 else if(pollfd
.revents
& POLLOUT
) {
140 d_iter
=d_writeCallbacks
.find(pollfd
.fd
);
142 if(d_iter
!= d_writeCallbacks
.end()) {
143 d_iter
->d_callback(d_iter
->d_fd
, d_iter
->d_parameter
);
153 void acceptData(int fd
, boost::any
& parameter
)
155 cout
<<"Have data on fd "<<fd
<<endl
;
156 Socket
* sock
=boost::any_cast
<Socket
*>(parameter
);
159 sock
->recvFrom(packet
, rem
);
160 cout
<<"Received "<<packet
.size()<<" bytes!\n";
166 Socket
s(AF_INET
, SOCK_DGRAM
);
168 IPEndpoint
loc("0.0.0.0", 2000);
171 PollFDMultiplexer sfm
;
173 sfm
.addReadFD(s
.getHandle(), &acceptData
, &s
);
175 for(int n
=0; n
< 100 ; ++n
) {
178 sfm
.removeReadFD(s
.getHandle());
179 sfm
.removeReadFD(s
.getHandle());