switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Socket / FileHandle.ih
1 // $Id$
2 //
3 // Copyright (C) 2006
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 FileHandle internal header
30  */
31
32 #ifndef IH_SENF_Socket_FileHandle_
33 #define IH_SENF_Socket_FileHandle_ 1
34
35 // Custom includes
36 #include <boost/intrusive_ptr.hpp>
37 #include <senf/Utils/intrusive_refcount.hh>
38 #include <senf/Utils/pool_alloc_mixin.hh>
39
40 //-/////////////////////////////////////////////////////////////////////////////////////////////////
41
42 namespace senf {
43
44     class FileHandle;
45
46     /** \brief FileHandle referenced body
47
48         \internal
49
50         The senf::FileBody class forms the body part of the handle/body structure of the FileHandle
51         interface. It manages the FileHandle data and is referenced by senf::FileHandle. It is
52         automatically managed using reference counting.
53
54         Since the senf::FileHandle class forwards most calls directly to the underlying
55         senf::FileBody instance, most members are documented in senf::FileHandle.
56
57         \section filebody_new Writing senf::FileBody derived classes
58
59         It is possible to write customized senf::FileBody derived body implementations. This
60         implementation can then be used be a senf::FileHandle derived class to customize the
61         FileHandle behavior. Handling the body directly by the handle class ensures, that no invalid
62         handles can be created (a senf::FileHandle derived handle expecting a specific body type but
63         pointing to a different body type).
64
65         To customize the behavior, a virtual interface is provided. This interface only covers some
66         basic functionality which is only used infrequently during the lifetime of a FileHandle
67         instance.
68
69         \attention Whenever a new class is derived from FileBody which adds new members, this class
70             \e must also derive from senf::pool_alloc_mixin
71       */
72     class FileBody
73         : public senf::intrusive_refcount,
74           public senf::pool_alloc_mixin<FileBody>
75     {
76     public:
77         //-/////////////////////////////////////////////////////////////////////////////////////////
78         // Types
79
80         typedef boost::intrusive_ptr<FileBody> ptr;
81
82         //-/////////////////////////////////////////////////////////////////////////////////////////
83         ///\name Structors and default members
84         //\{
85
86         explicit FileBody(int fd=-1);   ///< Create new instance
87                                         /**< You need to pass a real file descriptor to this
88                                            constructor not some arbitrary id even if you overload
89                                            all the virtual members. If the file descriptor is -1 the
90                                            resulting body/handle is not valid() */
91         virtual ~FileBody();
92
93         // NO DESTRUCTOR HERE (that is, only an empty virtual destructor) - destructors and virtual
94         // functions don't mix. What would be in the the destructor is in 'destroyClose()' which is
95         // called from FileHandle::~FileHandle() *before* the last handle dies.
96
97         // no copy
98         // no conversion constructors
99
100         //\}
101         //-/////////////////////////////////////////////////////////////////////////////////////////
102
103         FileHandle handle();
104
105         int fd() const;
106         void fd(int fd);
107
108         void close();
109         void terminate();
110         void destroyClose();
111
112         bool readable() const;
113         bool waitReadable(senf::ClockService::clock_type timeout) const;
114         bool writeable() const;
115         bool waitWriteable(senf::ClockService::clock_type timeout) const;
116         bool oobReadable() const;
117         bool waitOOBReadable(senf::ClockService::clock_type timeout) const;
118
119         bool blocking() const;
120         void blocking(bool status);
121
122         bool eof() const;
123         bool valid() const;
124
125     private:
126         //-/////////////////////////////////////////////////////////////////////////////////////////
127         // Virtual interface for subclasses to override
128
129         virtual void v_close();         ///< Called to close the file descriptor
130                                         /**< You should probably always call the global ::close()
131                                            function in this member, however you might want to do
132                                            some additional cleanup here. If the operation fails, you
133                                            are allowed to throw (preferably a
134                                            senf::SystemException).
135
136                                         \throws senf::SystemException */
137         virtual void v_terminate();     ///< Called to forcibly close the file descriptor
138                                         /**< This member is called by the destructor (and by
139                                            terminate()) to close the descriptor. This member must \e
140                                            never throw, it should probably just ignore error
141                                            conditions (there's not much else you can do) */
142         virtual bool v_eof() const;     ///< Called by eof()
143         virtual bool v_valid() const;   ///< Called by valid()
144                                         /**< This member is only called, if the file descriptor is
145                                            not -1 */
146
147     protected:
148
149     private:
150         bool pollCheck(int fd, bool incoming, int timeout, bool oob=false) const;
151
152         int fd_;
153     };
154
155 }
156
157 //-/////////////////////////////////////////////////////////////////////////////////////////////////
158 #endif
159
160 \f
161 // Local Variables:
162 // mode: c++
163 // fill-column: 100
164 // c-file-style: "senf"
165 // indent-tabs-mode: nil
166 // ispell-local-dictionary: "american"
167 // compile-command: "scons -u test"
168 // comment-column: 40
169 // End: