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