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