088e2d8a652c927052f96f057f11ab6fd5ef20ce
[senf.git] / senf / Scheduler / FdEvent.hh
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 FdDispatcher public header */
30
31 #ifndef HH_SENF_Scheduler_FdEvent_
32 #define HH_SENF_Scheduler_FdEvent_ 1
33
34 // Custom includes
35 #include <senf/boost_intrusive/iset_hook.hpp>
36 #include <senf/Utils/Exception.hh>
37 #include "FdManager.hh"
38 #include "FIFORunner.hh"
39
40 //#include "FdEvent.mpp"
41 //-/////////////////////////////////////////////////////////////////////////////////////////////////
42
43 namespace senf {
44 namespace scheduler {
45
46     namespace detail {
47         struct FdSetTag;
48         typedef boost::intrusive::iset_base_hook<FdSetTag> FdSetBase;
49         struct FdSetCompare;
50         struct FindFd;
51         class FdDispatcher;
52         class FileDispatcher;
53     }
54
55     /** \brief File descriptor event
56
57         The FdEvent class registers a file descriptor for read or write events.
58
59         There are a number of different event types supported for file descriptors. Those are
60         specified using a bit mask. Possible events are
61
62         \li \c EV_READ: File descriptor is readable (or at EOF)
63         \li \c EV_PRIO: There is out-of-band data available to be read on the file descriptor
64         \li \c EV_WRITE: File descriptor is writable
65
66         The callback will be called with one additional argument. This argument is the event mask of
67         type int. This mask will tell, which of the registered events are signaled. There are some
68         additional flags which can be set when calling the handler callback:
69
70         \li \c EV_HUP: The other end has closed the connection
71         \li \c EV_ERR: Transport error
72
73         Only a single handler may be registered for any combination of file descriptor and event
74         otherwise a DuplicateEventRegistrationException is thrown.
75
76         The file descriptor is specified using an arbitrary handle type which supports the \c
77         retrieve_filehandle() protocol: There must be a global function \c retrieve_filehandle
78         callable with the handle type. This function must return the file descriptor associated with
79         the handle. Implementations for integer numbers (explicit file descriptors) and senf socket
80         handles are provided.
81
82         The FdEvent class is an implementation of the RAII idiom: The event will be automatically
83         unregistered in the FdEvent destructor. The FdEvent instance should be created within the
84         same scope or on a scope below where the callback is defined (e.g. if the callback is a
85         member function it should be defined as a class member).
86      */
87     class FdEvent
88         : public detail::FIFORunner::TaskInfo,
89           public detail::FdSetBase,
90           public detail::FdManager::Event
91     {
92     public:
93         //-////////////////////////////////////////////////////////////////////////
94         // Types
95
96         typedef boost::function<void (int)> Callback;
97
98         enum Events {
99             EV_NONE = 0                             ///< No event
100           , EV_READ = detail::FdManager::EV_READ    ///< fd readable (or EOF)
101           , EV_PRIO = detail::FdManager::EV_PRIO    ///< OOB data available for read
102           , EV_WRITE = detail::FdManager::EV_WRITE  ///< fd writable
103           , EV_HUP = detail::FdManager::EV_HUP      ///< remote end closed connection
104           , EV_ERR = detail::FdManager::EV_ERR      ///< transport error
105           , EV_ALL = (detail::FdManager::EV_READ
106                       | detail::FdManager::EV_WRITE
107                       | detail::FdManager::EV_PRIO) ///< register all events (read, prio and write)
108         };
109
110         //-////////////////////////////////////////////////////////////////////////
111         ///\name Structors and default members
112         //\{
113
114         template <class Handle>
115         FdEvent(std::string const & name, Callback const & cb, Handle const & handle, int events,
116                 bool initiallyEnabled = true);
117                                         ///< Register a file descriptor event
118                                         /**< Registers \a cb to be called when any of the \a events
119                                              occurs on \a handle. If \a initiallyEnabled is set \c
120                                              false, the callback will not be enabled
121                                              automatically. Use enable() to do so.
122                                              \param[in] name Descriptive event name (purely
123                                                  informational)
124                                              \param[in] cb Callback to call
125                                              \param[in] handle Handle (file descriptor) to watch
126                                              \param[in] events Events to watch for (see Events enum)
127                                              \param[in] initiallyEnabled if set \c false, do not
128                                                  enable callback automatically. */
129         FdEvent(std::string const & name, Callback const & cb);
130                                         ///< Create a file descriptor event
131                                         /**< Creates a file descriptor event for callback \a cb. The
132                                              event is initially disabled. Use the other members to
133                                              set the missing parameters and enable the event.
134                                              \param[in] name Descriptive event name (purely
135                                                  informational)
136                                              \param[in] cb Callback to call. This callback may \e
137                                                  explicitly be set to \c 0 if the value cannot be
138                                                  initialized. */
139         ~FdEvent();
140
141         //\}
142         //-////////////////////////////////////////////////////////////////////////
143
144         void disable();                 ///< Disable event
145         void enable();                  ///< Enable event
146
147         FdEvent & action(Callback const & cb); ///< Change event callback
148
149         FdEvent & events(int events);   ///< Change event mask
150         FdEvent & addEvents(int events); ///< Add additional events to event mask
151         FdEvent & removeEvents(int events); ///< Remove events from event mask
152         int events();                   ///< Current event mask
153
154         template <class Handle>
155         FdEvent & handle(Handle const & handle); ///< Change event file handle
156
157         struct DuplicateEventRegistrationException : public Exception
158         { DuplicateEventRegistrationException() : Exception("duplicate fd event registration") {} };
159
160     protected:
161
162     private:
163         virtual void signal(int events);
164         virtual void v_run();
165         virtual char const * v_type() const;
166         virtual std::string v_info() const;
167
168         Callback cb_;
169         int fd_;
170         bool pollable_;
171         int events_;
172         int signaledEvents_;
173
174         friend class detail::FdSetCompare;
175         friend class detail::FindFd;
176         friend class detail::FdDispatcher;
177         friend class detail::FileDispatcher;
178     };
179
180     /** \brief Get file descriptor from handle object
181
182         This function will query the \a handle for it's file descriptor. The real implementation
183         must be provided by a freestanding function \c retrieve_filehandle(Handle const & h) within
184         the namespace of \a Handle.
185      */
186     template <class Handle>
187     int get_descriptor(Handle const & handle);
188 }}
189
190 //-/////////////////////////////////////////////////////////////////////////////////////////////////
191 #include "FdEvent.cci"
192 #include "FdEvent.ct"
193 #include "FdEvent.cti"
194 #endif
195
196 \f
197 // Local Variables:
198 // mode: c++
199 // fill-column: 100
200 // comment-column: 40
201 // c-file-style: "senf"
202 // indent-tabs-mode: nil
203 // ispell-local-dictionary: "american"
204 // compile-command: "scons -u test"
205 // End: