]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/pollmplexer.cc
remove all traces of selectmplexer, fix up pollmplexer
[thirdparty/pdns.git] / pdns / pollmplexer.cc
CommitLineData
870a0fe4
AT
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
cfa2996a
BH
4#include "mplexer.hh"
5#include "sstuff.hh"
6#include <iostream>
7#include <poll.h>
8#include "misc.hh"
10f4eea8 9#include "namespaces.hh"
cfa2996a 10
926444e2 11class PollFDMultiplexer : public FDMultiplexer
12{
13public:
14 PollFDMultiplexer()
15 {}
16 virtual ~PollFDMultiplexer()
17 {
18 }
19
20 virtual int run(struct timeval* tv, int timeout=500);
21
22 virtual void addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, const funcparam_t& parameter);
23 virtual void removeFD(callbackmap_t& cbmap, int fd);
24 string getName()
25 {
26 return "poll";
27 }
28private:
29};
cfa2996a
BH
30
31static FDMultiplexer* make()
32{
33 return new PollFDMultiplexer();
34}
35
36static struct RegisterOurselves
37{
38 RegisterOurselves() {
39 FDMultiplexer::getMultiplexerMap().insert(make_pair(1, &make));
40 }
41} doIt;
42
43void PollFDMultiplexer::addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, const boost::any& parameter)
44{
45 Callback cb;
46 cb.d_callback=toDo;
47 cb.d_parameter=parameter;
48 memset(&cb.d_ttd, 0, sizeof(cb.d_ttd));
49 if(cbmap.count(fd))
335da0ba 50 throw FDMultiplexerException("Tried to add fd "+std::to_string(fd)+ " to multiplexer twice");
cfa2996a
BH
51 cbmap[fd]=cb;
52}
53
54void PollFDMultiplexer::removeFD(callbackmap_t& cbmap, int fd)
55{
56 if(d_inrun && d_iter->first==fd) // trying to remove us!
57 d_iter++;
58
59 if(!cbmap.erase(fd))
335da0ba 60 throw FDMultiplexerException("Tried to remove unlisted fd "+std::to_string(fd)+ " from multiplexer");
cfa2996a
BH
61}
62
63bool pollfdcomp(const struct pollfd& a, const struct pollfd& b)
64{
65 return a.fd < b.fd;
66}
67
926444e2 68int PollFDMultiplexer::run(struct timeval* now, int timeout)
cfa2996a
BH
69{
70 if(d_inrun) {
71 throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!\n");
72 }
73
74 vector<struct pollfd> pollfds;
75
76 struct pollfd pollfd;
77 for(callbackmap_t::const_iterator i=d_readCallbacks.begin(); i != d_readCallbacks.end(); ++i) {
78 pollfd.fd = i->first;
79 pollfd.events = POLLIN;
80 pollfds.push_back(pollfd);
81 }
82
83 for(callbackmap_t::const_iterator i=d_writeCallbacks.begin(); i != d_writeCallbacks.end(); ++i) {
84 pollfd.fd = i->first;
85 pollfd.events = POLLOUT;
86 pollfds.push_back(pollfd);
87 }
88
0e663c3b
RG
89 int ret=poll(&pollfds[0], pollfds.size(), timeout);
90 gettimeofday(now, 0); // MANDATORY!
cfa2996a
BH
91
92 if(ret < 0 && errno!=EINTR)
93 throw FDMultiplexerException("poll returned error: "+stringerror());
94
95 d_iter=d_readCallbacks.end();
96 d_inrun=true;
0e663c3b 97
cfa2996a
BH
98 for(unsigned int n = 0; n < pollfds.size(); ++n) {
99 if(pollfds[n].revents == POLLIN) {
100 d_iter=d_readCallbacks.find(pollfds[n].fd);
101
102 if(d_iter != d_readCallbacks.end()) {
103 d_iter->second.d_callback(d_iter->first, d_iter->second.d_parameter);
104 continue; // so we don't refind ourselves as writable!
105 }
106 }
107 else if(pollfds[n].revents == POLLOUT) {
108 d_iter=d_writeCallbacks.find(pollfds[n].fd);
109
110 if(d_iter != d_writeCallbacks.end()) {
111 d_iter->second.d_callback(d_iter->first, d_iter->second.d_parameter);
112 }
113 }
114 }
115 d_inrun=false;
0e663c3b 116 return ret;
cfa2996a
BH
117}
118
119#if 0
120
121void acceptData(int fd, boost::any& parameter)
122{
123 cout<<"Have data on fd "<<fd<<endl;
124 Socket* sock=boost::any_cast<Socket*>(parameter);
125 string packet;
126 IPEndpoint rem;
127 sock->recvFrom(packet, rem);
128 cout<<"Received "<<packet.size()<<" bytes!\n";
129}
130
131
132int main()
133{
a5794017 134 Socket s(AF_INET, SOCK_DGRAM);
cfa2996a
BH
135
136 IPEndpoint loc("0.0.0.0", 2000);
137 s.bind(loc);
138
139 PollFDMultiplexer sfm;
140
141 sfm.addReadFD(s.getHandle(), &acceptData, &s);
142
143 for(int n=0; n < 100 ; ++n) {
144 sfm.run();
145 }
146 sfm.removeReadFD(s.getHandle());
147 sfm.removeReadFD(s.getHandle());
148}
149#endif
150