switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Scheduler / Poller.ct
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief Poller non-inline template implementation  */
30
31 //#include "Poller.ih"
32
33 // Custom includes
34 #include <errno.h>
35 #include <senf/Utils/Exception.hh>
36
37 #define prefix_
38 //-/////////////////////////////////////////////////////////////////////////////////////////////////
39
40 template <class Value>
41 prefix_ bool senf::scheduler::detail::Poller<Value>::set(int fd, int events, Value * data)
42 {
43     struct epoll_event ev = { events, { data } };
44     if (epoll_ctl(epollFd_, EPOLL_CTL_ADD, fd, &ev) != -1)
45         return true;
46     if (errno == EEXIST)
47         if (epoll_ctl(epollFd_, EPOLL_CTL_MOD, fd, &ev) != -1)
48             return true;
49     if (errno == EPERM)
50         return false;
51     SENF_THROW_SYSTEM_EXCEPTION("epolll_ctl()");
52 }
53
54 template <class Value>
55 prefix_ void senf::scheduler::detail::Poller<Value>::remove(int fd)
56 {
57     if (epoll_ctl(epollFd_, EPOLL_CTL_DEL, fd, 0) == -1)
58         if (errno != ENOENT && errno != EBADF && errno != EPERM)
59             // Calling remove() on a file descriptor which is not registered
60             // is no error, it shall be ignored:
61             // ENOENT: Not part of the poller but a valid (open) fd
62             // EBADF: The fd has been closed already. The kernel automatically removes such fds
63             //     from epoll structures
64             // EPERM: The fd does not support epoll and thus can never have been added
65             SENF_THROW_SYSTEM_EXCEPTION("epoll_ctl()");
66 }
67
68 template <class Value>
69 prefix_ typename senf::scheduler::detail::Poller<Value>::range senf::scheduler::detail::Poller<Value>::wait()
70 {
71     static epoll_event events[NumEvents];
72     int rv (0);
73     rv = epoll_wait(epollFd_, events, NumEvents, timeout_);
74     if (rv == -1) {
75         if (errno == EINTR)
76             rv = 0;
77         else
78             SENF_THROW_SYSTEM_EXCEPTION("epoll_wait()");
79     }
80     return boost::make_iterator_range(
81         boost::make_transform_iterator(events, GetPollResult()),
82         boost::make_transform_iterator(events+rv, GetPollResult()) );
83 }
84
85 //-/////////////////////////////////////////////////////////////////////////////////////////////////
86 #undef prefix_
87
88 \f
89 // Local Variables:
90 // mode: c++
91 // fill-column: 100
92 // comment-column: 40
93 // c-file-style: "senf"
94 // indent-tabs-mode: nil
95 // ispell-local-dictionary: "american"
96 // compile-command: "scons -u test"
97 // End: