• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PowerDNS / pdns / 12321902803

13 Dec 2024 07:34PM UTC coverage: 66.359% (+1.6%) from 64.78%
12321902803

Pull #14970

github

web-flow
Merge e3a7df61c into 3dfd8e317
Pull Request #14970: boost > std optional

26084 of 54744 branches covered (47.65%)

Branch coverage included in aggregate %.

14 of 15 new or added lines in 2 files covered. (93.33%)

1863 existing lines in 52 files now uncovered.

85857 of 113946 relevant lines covered (75.35%)

4412729.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.01
/pdns/pollmplexer.cc
1
#ifdef HAVE_CONFIG_H
2
#include "config.h"
3
#endif
4
#include "mplexer.hh"
5
#include "sstuff.hh"
6
#include <iostream>
7
#include <poll.h>
8
#include <unordered_map>
9
#include "misc.hh"
10
#include "namespaces.hh"
11

12
FDMultiplexer* FDMultiplexer::getMultiplexerSilent(unsigned int maxEventsHint)
13
{
6✔
14
  FDMultiplexer* ret = nullptr;
6✔
15
  for (const auto& i : FDMultiplexer::getMultiplexerMap()) {
6!
16
    try {
6✔
17
      ret = i.second(std::min(maxEventsHint, FDMultiplexer::s_maxevents));
6✔
18
      return ret;
6✔
19
    }
6✔
20
    catch (const FDMultiplexerException& fe) {
6✔
UNCOV
21
    }
×
22
    catch (...) {
6✔
23
    }
×
24
  }
6✔
UNCOV
25
  return ret;
×
26
}
6✔
27

28
class PollFDMultiplexer : public FDMultiplexer
29
{
30
public:
31
  PollFDMultiplexer(unsigned int /* maxEventsHint */)
32
  {}
6✔
33

34
  int run(struct timeval* tv, int timeout = 500) override;
35
  void getAvailableFDs(std::vector<int>& fds, int timeout) override;
36

37
  void addFD(int fd, FDMultiplexer::EventKind) override;
38
  void removeFD(int fd, FDMultiplexer::EventKind) override;
39

40
  string getName() const override
41
  {
×
42
    return "poll";
×
43
  }
×
44

45
private:
46
  std::unordered_map<int, struct pollfd> d_pollfds;
47
  vector<struct pollfd> preparePollFD() const;
48
};
49

50
static FDMultiplexer* make(unsigned int maxEventsHint)
51
{
6✔
52
  return new PollFDMultiplexer(maxEventsHint);
6✔
53
}
6✔
54

55
static struct RegisterOurselves
56
{
57
  RegisterOurselves()
58
  {
161✔
59
    FDMultiplexer::getMultiplexerMap().emplace(2, &make);
161✔
60
  }
161✔
61
} doIt;
62

63
static int convertEventKind(FDMultiplexer::EventKind kind)
64
{
21✔
65
  switch (kind) {
21!
66
  case FDMultiplexer::EventKind::Read:
6✔
67
    return POLLIN;
6✔
68
  case FDMultiplexer::EventKind::Write:
12✔
69
    return POLLOUT;
12✔
70
  case FDMultiplexer::EventKind::Both:
3✔
71
    return POLLIN | POLLOUT;
3✔
72
  }
21✔
73
  throw std::runtime_error("Unhandled event kind in the ports multiplexer");
×
74
}
21✔
75

76
void PollFDMultiplexer::addFD(int fd, FDMultiplexer::EventKind kind)
77
{
21✔
78
  if (d_pollfds.count(fd) == 0) {
21✔
79
    auto& pollfd = d_pollfds[fd];
18✔
80
    pollfd.fd = fd;
18✔
81
    pollfd.events = 0;
18✔
82
  }
18✔
83
  auto& pollfd = d_pollfds.at(fd);
21✔
84
  pollfd.events |= convertEventKind(kind);
21✔
85
}
21✔
86

87
void PollFDMultiplexer::removeFD(int fd, FDMultiplexer::EventKind)
88
{
18✔
89
  d_pollfds.erase(fd);
18✔
90
}
18✔
91

92
vector<struct pollfd> PollFDMultiplexer::preparePollFD() const
93
{
51✔
94
  std::vector<struct pollfd> result;
51✔
95
  result.reserve(d_pollfds.size());
51✔
96
  for (const auto& entry : d_pollfds) {
51✔
97
    result.push_back(entry.second);
45✔
98
  }
45✔
99

100
  return result;
51✔
101
}
51✔
102

103
void PollFDMultiplexer::getAvailableFDs(std::vector<int>& fds, int timeout)
104
{
27✔
105
  auto pollfds = preparePollFD();
27✔
106
  if (pollfds.empty()) {
27✔
107
    return;
6✔
108
  }
6✔
109

110
  int ret = poll(&pollfds[0], pollfds.size(), timeout);
21✔
111

112
  if (ret < 0 && errno != EINTR) {
21!
113
    throw FDMultiplexerException("poll returned error: " + stringerror());
×
114
  }
×
115

116
  for (const auto& pollfd : pollfds) {
24✔
117
    if (pollfd.revents & POLLIN || pollfd.revents & POLLOUT || pollfd.revents & POLLERR || pollfd.revents & POLLHUP) {
24!
118
      fds.push_back(pollfd.fd);
21✔
119
    }
21✔
120
  }
24✔
121
}
21✔
122

123
int PollFDMultiplexer::run(struct timeval* now, int timeout)
124
{
24✔
125
  InRun guard(d_inrun);
24✔
126

127
  auto pollfds = preparePollFD();
24✔
128
  if (pollfds.empty()) {
24✔
129
    gettimeofday(now, nullptr); // MANDATORY!
6✔
130
    return 0;
6✔
131
  }
6✔
132

133
  int ret = poll(&pollfds[0], pollfds.size(), timeout);
18✔
134
  gettimeofday(now, nullptr); // MANDATORY!
18✔
135

136
  if (ret < 0 && errno != EINTR) {
18!
137
    throw FDMultiplexerException("poll returned error: " + stringerror());
×
138
  }
×
139

140
  int count = 0;
18✔
141
  for (const auto& pollfd : pollfds) {
21✔
142
    if (pollfd.revents & POLLIN || pollfd.revents & POLLERR || pollfd.revents & POLLHUP) {
21!
143
      const auto& iter = d_readCallbacks.find(pollfd.fd);
9✔
144
      if (iter != d_readCallbacks.end()) {
9!
145
        iter->d_callback(iter->d_fd, iter->d_parameter);
9✔
146
        count++;
9✔
147
      }
9✔
148
    }
9✔
149

150
    if (pollfd.revents & POLLOUT || pollfd.revents & POLLERR) {
21!
151
      const auto& iter = d_writeCallbacks.find(pollfd.fd);
12✔
152
      if (iter != d_writeCallbacks.end()) {
12!
153
        iter->d_callback(iter->d_fd, iter->d_parameter);
12✔
154
        count++;
12✔
155
      }
12✔
156
    }
12✔
157
  }
21✔
158

159
  return count;
18✔
160
}
18✔
161

162
#if 0
163

164
void acceptData(int fd, boost::any& parameter)
165
{
166
  cout<<"Have data on fd "<<fd<<endl;
167
  Socket* sock=boost::any_cast<Socket*>(parameter);
168
  string packet;
169
  IPEndpoint rem;
170
  sock->recvFrom(packet, rem);
171
  cout<<"Received "<<packet.size()<<" bytes!\n";
172
}
173

174

175
int main()
176
{
177
  Socket s(AF_INET, SOCK_DGRAM);
178

179
  IPEndpoint loc("0.0.0.0", 2000);
180
  s.bind(loc);
181

182
  PollFDMultiplexer sfm;
183

184
  sfm.addReadFD(s.getHandle(), &acceptData, &s);
185

186
  for(int n=0; n < 100 ; ++n) {
187
    sfm.run();
188
  }
189
  sfm.removeReadFD(s.getHandle());
190
  sfm.removeReadFD(s.getHandle());
191
}
192
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc