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