FdEvent.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #include "FdEvent.hh"
18 #include "FdEvent.ih"
19 
20 // Custom includes
21 #include <sstream>
22 
23 //#include "FdEvent.mpp"
24 #define prefix_
25 //-/////////////////////////////////////////////////////////////////////////////////////////////////
26 
27 //-/////////////////////////////////////////////////////////////////////////////////////////////////
28 // senf::scheduler::detail::FdDispatcher
29 
30 prefix_ senf::scheduler::detail::FdDispatcher::~FdDispatcher()
31 {
32  for (FdSet::iterator i (fds_.begin()); i != fds_.end(); ++i) {
33  detail::FdManager::instance().remove(i->fd_);
34  detail::FIFORunner::instance().dequeue(&(*i));
35  }
36 }
37 
38 prefix_ bool senf::scheduler::detail::FdDispatcher::add(FdEvent & event)
39 {
40  std::pair<FdSet::iterator,FdSet::iterator> range (fds_.equal_range(event));
41  int events (0);
42  for (FdSet::iterator i (range.first); i != range.second; ++i)
43  events |= i->events_;
44  if (event.events_ & events)
45  throw FdEvent::DuplicateEventRegistrationException() << "vinfo: " << event.v_info();
46 
47  if (! detail::FdManager::instance().set(event.fd_, events | event.events_, &event))
48  return false;
49 
50  detail::FIFORunner::instance().enqueue(&event);
51  fds_.insert(range.first, event);
52 
53  return true;
54 }
55 
56 prefix_ void senf::scheduler::detail::FdDispatcher::remove(FdEvent & event)
57 {
58  fds_.erase(FdSet::s_iterator_to(event));
59  detail::FIFORunner::instance().dequeue(&event);
60 
61  std::pair<FdSet::iterator,FdSet::iterator> range (fds_.equal_range(event));
62  if (range.first == range.second)
63  detail::FdManager::instance().remove(event.fd_);
64  else {
65  int events (0);
66  for (FdSet::iterator i (range.first); i != range.second; ++i)
67  events |= i->events_;
68  detail::FdManager::instance().set(event.fd_, events, &(*range.first));
69  }
70 }
71 
72 //-/////////////////////////////////////////////////////////////////////////////////////////////////
73 // senf::scheduler::detail::FileDispatcher
74 
75 prefix_ void senf::scheduler::detail::FileDispatcher::add(FdEvent & event)
76 {
77  std::pair<FdSet::iterator,FdSet::iterator> range (fds_.equal_range(event));
78  int events (0);
79  for (FdSet::iterator i (range.first); i != range.second; ++i)
80  events |= i->events_;
81  if (event.events_ & events)
82  throw FdEvent::DuplicateEventRegistrationException() << "vinfo: " << event.v_info();
83 
84  detail::FIFORunner::instance().enqueue(&event);
85  fds_.insert(range.first, event);
86 
87  detail::FdManager::instance().timeout(0);
88 }
89 
90 prefix_ senf::scheduler::detail::FileDispatcher::FileDispatcher()
91  : managerTimeout_ (scheduler::detail::FdManager::instance().timeout())
92 {}
93 
94 prefix_ senf::scheduler::detail::FileDispatcher::~FileDispatcher()
95 {
96  detail::FdManager::instance().timeout(-1);
97  for (FdSet::iterator i (fds_.begin()); i != fds_.end(); ++i)
98  detail::FIFORunner::instance().dequeue(&(*i));
99 }
100 
101 prefix_ void senf::scheduler::detail::FileDispatcher::prepareRun()
102 {
103  for (FdSet::iterator i (fds_.begin()); i != fds_.end(); ++i) {
104  i->signaledEvents_ = i->events_;
105  i->setRunnable();
106  }
107 }
108 
109 prefix_ void senf::scheduler::detail::FileDispatcher::remove(FdEvent & event)
110 {
111  fds_.erase(FdSet::s_iterator_to(event));
112  detail::FIFORunner::instance().dequeue(&event);
113  if (fds_.empty())
114  detail::FdManager::instance().timeout(managerTimeout_);
115 }
116 
117 //-/////////////////////////////////////////////////////////////////////////////////////////////////
118 // senf::scheduler::FdEvent
119 
121 {
122  if (enabled()) {
123  if (pollable_)
124  detail::FdDispatcher::instance().remove(*this);
125  else
126  detail::FileDispatcher::instance().remove(*this);
127  }
128 }
129 
131 {
132  if (! enabled() && events_ && fd_ != -1) {
133  if (pollable_ && detail::FdDispatcher::instance().add(*this))
134  return;
135  detail::FileDispatcher::instance().add(*this);
136  pollable_ = false;
137  }
138 }
139 
141 {
142  bool en = enabled();
143  disable();
144  events_ = events;
145  if (en)
146  enable();
147  return *this;
148 }
149 
150 prefix_ void senf::scheduler::FdEvent::signal(int events)
151 {
152  detail::FdDispatcher::FdSet::iterator i (detail::FdDispatcher::FdSet::s_iterator_to(*this));
153  detail::FdDispatcher::FdSet::iterator const i_end (detail::FdDispatcher::instance().fds_.end());
154  bool all ((events & (EV_ERR | EV_HUP)) && ! (events & (EV_READ | EV_PRIO | EV_WRITE)));
155  for (; i != i_end && fd_ == i->fd_; ++i) {
156  i->signaledEvents_ = events & (EV_ERR | EV_HUP | i->events_);
157  if (i->events_ & events || all)
158  i->setRunnable();
159  }
160 }
161 
162 prefix_ void senf::scheduler::FdEvent::v_run()
163 {
164  cb_(signaledEvents_);
165 }
166 
167 prefix_ char const * senf::scheduler::FdEvent::v_type()
168  const
169 {
170  return "fd";
171 }
172 
173 prefix_ std::string senf::scheduler::FdEvent::v_info()
174  const
175 {
176  std::stringstream ss;
177 
178  ss << "fd " << fd_;
179  if (! pollable_)
180  ss << " (NOT pollable)";
181  if (events_ & EV_READ)
182  ss << " READ";
183  if (events_ & EV_PRIO)
184  ss << " PRIO";
185  if (events_ & EV_WRITE)
186  ss << " WRITE";
187  return ss.str();
188 }
189 
190 //-/////////////////////////////////////////////////////////////////////////////////////////////////
191 #undef prefix_
192 //#include "FdEvent.mpp"
193 
194 
195 // Local Variables:
196 // mode: c++
197 // fill-column: 100
198 // comment-column: 40
199 // c-file-style: "senf"
200 // indent-tabs-mode: nil
201 // ispell-local-dictionary: "american"
202 // compile-command: "scons -u test"
203 // End:
fd readable (or EOF)
Definition: FdEvent.hh:85
bool enabled() const
true, if event is enabled, false otherwise
File descriptor event.
Definition: FdEvent.hh:72
#define prefix_
Definition: FdEvent.cc:24
void disable()
Disable event.
Definition: FdEvent.cc:120
FdDispatcher public header.
void enable()
Enable event.
Definition: FdEvent.cc:130
remote end closed connection
Definition: FdEvent.hh:88
OOB data available for read.
Definition: FdEvent.hh:86
int events()
Current event mask.