50ddaaf7e1327aefd1c58d99b6770916f130ed35
[senf.git] / senf / Socket / FileHandle.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief FileHandle public header
25  */
26
27 /** \defgroup handle_group The Handle Hierarchy
28
29     \diaimage FhHierarchy.dia
30
31     The senf::FileHandle class is the base of a hierarchy of socket handle classes (realized as
32     templates). These classes provide an interface to the complete socket API. While going down the
33     inheritance hierarchy, the interface will be more and more complete.
34
35     The most complete interface is provided by senf::ProtocolClientSocketHandle and
36     senf::ProtocolServerSocketHandle. The template Arguments specifies the Protocol class of the
37     underlying socket type. These are the \e only classes having public constructors and are
38     therefore the only classes, which may be created by the library user. You will normally use
39     these classes by naming a specific socket typedef (e.g. senf::TCPv4ClientSocketHandle).
40
41     However, to aid writing flexible and generic code, the socket library provides the
42     senf::ClientSocketHandle and senf::ServerSocketHandle class templates. These templates implement
43     a family of closely related classes based on the specification of the socket policy. This policy
44     specification may be \e incomplete (see below). Instances of
45     senf::ClientSocketHandle/senf::ServerSocketHandle can be assigned and converted to different
46     ClientSocketHandle/ServerSocketHandle types as long as the policy specifications are compatible.
47
48     \attention It is very important, to (almost) always pass the socket handle <em>by
49     value</em>. The socket handle is a very lightweight class and designed to be used like an
50     ordinary built-in type. This is very important in combination with the policy interface.
51
52     \note The FileHandle hierarchy below the SocketHandle template is \e not meant to be user
53     extensible. To add new socket types, you should introduce new protocol and/or policy classes,
54     the SocketHandle classes should not be changed.
55  */
56
57 #ifndef HH_SENF_Socket_FileHandle_
58 #define HH_SENF_Socket_FileHandle_ 1
59
60 // Custom includes
61 #include <memory> // std::auto_ptr
62 #include <senf/Utils/safe_bool.hh>
63 #include <senf/Scheduler/ClockService.hh>
64
65 //#include "FileHandle.mpp"
66 ///////////////////////////////hh.p////////////////////////////////////////
67 #include "FileHandle.ih"
68
69 namespace senf {
70
71     /// \addtogroup handle_group
72     /// @{
73
74     /** \brief Basic file handle wrapper
75
76         senf::FileHandle provides a simple wrapper for arbitrary file handles. It exposes only a
77         minimal interface which does \e not include reading or writing (since some filehandles are
78         not readable or writable or only using special function calls like sendto).
79
80         The FileHandle class provides handle/body handling and uses automatic reference
81         counting. The senf::FileHandle instance is very lightweight and should be used like a
82         built-in type.
83
84         \attention You should mostly pass around senf::FileHandle objects by \e value and not by
85         reference.
86
87         The FileHandle abstraction is only applicable to real filehandles. It is \e not possible to
88         wrap any provider or consumer into a filehandle like interface using this wrapper. The
89         wrapper will forward some calls directly to the underlying API without relying on virtual
90         methods. This allows important members to be inlined.
91
92         It is not possible to use the senf::FileHandle class directly since it does not have any
93         public constructor. The FileHandle class is however the baseclass of all handle classes of
94         the socket library.
95
96         \section filehandle_new Writing senf::FileHandle derived classes
97
98         To build a new FileHandle type you need to derive from senf::FileHandle. The derived class
99         will have to call the protected FileHandle constructor passing a new senf::FileBody
100         instance. This instance may either be a simple senf::FileBody or a class derived from
101         senf::FileBody.
102      */
103     class FileHandle
104         : public safe_bool<FileHandle>
105     {
106     public:
107         ///////////////////////////////////////////////////////////////////////////
108         // Types
109
110         ///////////////////////////////////////////////////////////////////////////
111         ///\name Structors and default members
112         ///@{
113
114         FileHandle();
115         ~FileHandle();
116
117         // my default constructor
118         // default copy constructor
119         // default copy assignment
120         // default destructor
121
122         // no conversion constructors
123
124         ///@}
125         ///////////////////////////////////////////////////////////////////////////
126
127         void close();                ///< Close filehandle
128                                      /**< \throws senf::SystemException */
129         void terminate();            ///< Close filehandle ignoring error conditions
130
131         bool readable() const;       ///< Check, whether a read on the handle would not block
132                                      ///< (ignoring blocking state)
133         bool waitReadable(senf::ClockService::clock_type timeout = -1) const;
134                                      ///< Wait, until read on the handle would not block (ignoring
135                                      ///< blocking state)
136                                      /**< \param[in] timeout max time to wait, default is to wait
137                                               forever.
138                                           \returns \c true, if handle became readable or \c false on
139                                               timeout. */
140         bool writeable() const;      ///< Check, whether a write on the handle would not block
141                                      ///< (ignoring blocking state)
142         bool waitWriteable(senf::ClockService::clock_type timeout = -1) const;
143                                      ///< Wait, until a write on the handle would not block
144                                      ///< (ignoring blocking state)
145                                      /**< \param[in] timeout max time to wait, default is to wait
146                                               forever.
147                                           \returns \c true, if handle became writable or \c false on
148                                               timeout. */
149         bool oobReadable() const;    ///< Check, whether a read of prioritized data on the handle
150                                      ///< would not block (ignoring blocking state)
151         bool waitOOBReadable(senf::ClockService::clock_type timeout = -1) const;
152                                      ///< Wait, until read of prioritized data on the handle does
153                                      ///< not block (ignoring blocking state)
154                                      /**< \param[in] timeout max time to wait, default is to wait
155                                               forever.
156                                           \returns \c true, if handle became readable for
157                                               out-of-band data or \c false on timeout. */
158
159         bool blocking() const;       ///< Return current blocking state
160         void blocking(bool status);  ///< Set blocking state
161
162         bool eof() const;            ///< Check EOF condition
163                                      /**< Depending on the socket type, this might never return \p
164                                         true.
165
166                                         This member is somewhat problematic performance wise if
167                                         called frequently since it relies on virtual
168                                         functions. However, since the eof() handling is extremely
169                                         protocol dependent, a policy based implementation does not
170                                         seam feasible. */
171         bool valid() const;          ///< Check filehandle validity
172                                      /**< Any operation besides valid() will fail on an invalid
173                                         FileHandle */
174
175         bool boolean_test() const;  ///< Short for valid() && ! eof()
176                                     /**< This is called when using a FileHandle instance in a boolean
177                                        context
178
179                                        See the performance comments for the eof() member */
180
181         int fd() const;             ///< Return the raw FileHandle
182
183         static FileHandle cast_static(FileHandle handle);  /**< \internal */
184         static FileHandle cast_dynamic(FileHandle handle); /**< \internal */
185
186     protected:
187         explicit FileHandle(std::auto_ptr<FileBody> body);
188                                     ///< create new FileHandle instance
189                                     /**< The FileHandle instance will take over ownership over the
190                                        given FileBody instance which must have been allocated using
191                                        \c new. To configure the FileHandle behavior, A derived class
192                                        may provide any class derived from FileBody here. */
193
194         explicit FileHandle(FileBody::ptr body);
195
196         FileBody & body();          ///< Access body
197         FileBody const & body() const; ///< Access body in const context
198         static FileBody & body(FileHandle & handle); ///< Access body of another FileHandle instance
199         static FileBody const & body(FileHandle const & handle); ///< Access body of another
200                                     ///< FileHandle instance in const context
201
202         void fd(int fd);            ///< Set raw filehandle
203
204     private:
205         FileBody::ptr body_;
206
207         friend class FileBody;
208     };
209
210     /** \brief Adapt FileHandle to senf::scheduler
211         \related senf::FileHandle
212
213         \internal
214
215         This function will be called by the Scheduler to retrieve the file descriptor of the
216         FileHandle.
217      */
218     int retrieve_filehandle(FileHandle handle);
219
220     /// @}
221
222 }
223
224 ///////////////////////////////hh.e////////////////////////////////////////
225 #include "FileHandle.cci"
226 //#include "FileHandle.ct"
227 //#include "FileHandle.cti"
228 #endif
229
230 \f
231 // Local Variables:
232 // mode: c++
233 // fill-column: 100
234 // c-file-style: "senf"
235 // indent-tabs-mode: nil
236 // ispell-local-dictionary: "american"
237 // compile-command: "scons -u test"
238 // comment-column: 40
239 // End: