Poller.ct
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 
14 /** \file
15  \brief Poller non-inline template implementation */
16 
17 //#include "Poller.ih"
18 
19 // Custom includes
20 #include <errno.h>
21 #include <senf/Utils/Exception.hh>
22 #include <senf/Utils/senflikely.hh>
23 
24 #define prefix_
25 //-/////////////////////////////////////////////////////////////////////////////////////////////////
26 
27 template <class Value>
28 prefix_ bool senf::scheduler::detail::Poller<Value>::set(int fd, int events, Value * data)
29 {
30  struct epoll_event ev = { uint32_t(events), { data } };
31  if (epoll_ctl(epollFd_, EPOLL_CTL_ADD, fd, &ev) != -1)
32  return true;
33  if (errno == EEXIST)
34  if (epoll_ctl(epollFd_, EPOLL_CTL_MOD, fd, &ev) != -1)
35  return true;
36  if (errno == EPERM)
37  return false;
38  SENF_THROW_SYSTEM_EXCEPTION("epolll_ctl()");
39 }
40 
41 template <class Value>
42 prefix_ void senf::scheduler::detail::Poller<Value>::remove(int fd)
43 {
44  if (epoll_ctl(epollFd_, EPOLL_CTL_DEL, fd, 0) == -1)
45  if (errno != ENOENT && errno != EBADF && errno != EPERM)
46  // Calling remove() on a file descriptor which is not registered
47  // is no error, it shall be ignored:
48  // ENOENT: Not part of the poller but a valid (open) fd
49  // EBADF: The fd has been closed already. The kernel automatically removes such fds
50  // from epoll structures
51  // EPERM: The fd does not support epoll and thus can never have been added
52  SENF_THROW_SYSTEM_EXCEPTION("epoll_ctl()");
53 }
54 
55 template <class Value>
56 prefix_ typename senf::scheduler::detail::Poller<Value>::range senf::scheduler::detail::Poller<Value>::wait()
57 {
58  static epoll_event events[NumEvents];
59  int rv (epoll_wait(epollFd_, events, NumEvents, timeout_));
60  if (SENF_UNLIKELY(rv == -1)) {
61  if (errno == EINTR)
62  rv = 0;
63  else
64  SENF_THROW_SYSTEM_EXCEPTION("epoll_wait()");
65  }
66  return boost::make_iterator_range(
67  boost::make_transform_iterator(events, GetPollResult()),
68  boost::make_transform_iterator(events+rv, GetPollResult()) );
69 }
70 
71 //-/////////////////////////////////////////////////////////////////////////////////////////////////
72 #undef prefix_
73 
74 
75 // Local Variables:
76 // mode: c++
77 // fill-column: 100
78 // comment-column: 40
79 // c-file-style: "senf"
80 // indent-tabs-mode: nil
81 // ispell-local-dictionary: "american"
82 // compile-command: "scons -u test"
83 // End: