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