VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
geventhandler.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file geventhandler.h
19 ///
20 
21 #ifndef G_EVENT_HANDLER_H
22 #define G_EVENT_HANDLER_H
23 
24 #include "gdef.h"
25 #include "gnet.h"
26 #include "gdatetime.h"
27 #include "gdescriptor.h"
28 #include <vector>
29 #include <string>
30 
31 namespace GNet
32 {
33  class EventHandler ;
34  class EventExceptionHandler ;
35  class EventHandlerList ;
36  class TimerList ;
37 }
38 
39 /// \class GNet::EventExceptionHandler
40 /// An abstract interface for handling exceptions thrown out of event-loop
41 /// callbacks (socket events and timer events). If the handler just rethrows
42 /// then the event loop will terminate.
43 ///
45 {
46 public:
47  virtual void onException( std::exception & ) = 0 ;
48  ///< Called by the event loop when an exception is thrown out
49  ///< of an event loop callback.
50  ///<
51  ///< The implementation may just do a "throw" to throw the current
52  ///< exception out of the event loop, or a "delete this" for
53  ///< objects that manage themselves on the heap.
54  ///<
55  ///< EventHandler objects or timer objects that are sub-objects
56  ///< of other EventHandler objects will normally have their
57  ///< implementation of onException() delegate to the outer
58  ///< object's onException().
59 
60 protected:
61  virtual ~EventExceptionHandler() ;
62  ///< Destructor.
63 
64 private:
65  void operator=( const EventExceptionHandler & ) ;
66 } ;
67 
68 /// \class GNet::EventHandler
69 /// A base class for classes that handle asynchronous events from the event loop.
70 ///
71 /// An event handler object has its virtual methods called when an event is
72 /// detected on the associated file descriptor.
73 ///
74 /// If an event handler throws an exception which is caught by the event loop
75 /// then the event loop calls the handler's EventExceptionHandler::onException()
76 /// method.
77 ///
79 {
80 public:
81  virtual ~EventHandler() ;
82  ///< Destructor.
83 
84  virtual void readEvent() ;
85  ///< Called for a read event. Overridable. The default
86  ///< implementation does nothing.
87 
88  virtual void writeEvent() ;
89  ///< Called for a write event. Overrideable. The default
90  ///< implementation does nothing.
91 
92  virtual void exceptionEvent() ;
93  ///< Called for a socket-exception event. Overridable. The default
94  ///< implementation throws an exception resulting in a call to
95  ///< GNet::EventExceptionHandler::onException().
96 
97 private:
98  void operator=( const EventHandler & ) ;
99 } ;
100 
101 /// \class GNet::EventHandlerList
102 /// A class that maps from a file descriptor to an event handler, used in the
103 /// implemention of classes derived from GNet::EventLoop.
104 ///
106 {
107 public:
108  struct Iterator /// An iterator for file-descriptor/handler-function pairs in a GNet::EventHandlerList.
109  {
110  typedef std::pair<Descriptor,EventHandler*> Pair ;
111  Iterator( const std::vector<Pair> & , bool ) ;
112  Iterator & operator++() ;
113  const Pair & operator*() const ;
114  bool operator==( const Iterator & ) const ;
115  bool operator!=( const Iterator & ) const ;
116  Descriptor fd() const ;
117  EventHandler * handler() ;
118  std::vector<Pair>::const_iterator m_p ;
119  std::vector<Pair>::const_iterator m_end ;
120  } ;
121 
122 public:
123  explicit EventHandlerList( const std::string & type ) ;
124  ///< Constructor. The type parameter (eg. "read") is used only in
125  ///< debugging messages.
126 
127  void add( Descriptor fd , EventHandler * handler ) ;
128  ///< Adds a file-descriptor/handler pair to the list.
129 
130  void remove( Descriptor fd ) ;
131  ///< Removes a file-descriptor from the list.
132 
133  bool contains( Descriptor fd ) const ;
134  ///< Returns true if the list contains the given file-descriptor.
135 
136  EventHandler * find( Descriptor fd ) ;
137  ///< Finds the handler associated with the given file descriptor.
138 
139  void lock() ;
140  ///< To be called at the start of an begin()/end() iteration if the
141  ///< list might change during the iteration. Must be paired with
142  ///< unlock().
143 
144  void unlock() ;
145  ///< Called at the end of a begin()/end() iteration to match a call
146  ///< to lock(). Does garbage collection.
147 
148  void collectGarbage() ;
149  ///< Collects garbage resulting from remove()s. Automatically called
150  ///< from unlock().
151 
152  Iterator begin() const ;
153  ///< Returns a forward iterator.
154 
155  Iterator end() const ;
156  ///< Returns an end iterator.
157 
158 private:
159  typedef std::vector<Iterator::Pair> List ;
161  void operator=( const EventHandlerList & ) ;
162  static bool contains( const List & , Descriptor fd ) ;
163  static EventHandler * find( List & , Descriptor fd ) ;
164  static void add( List & list , Descriptor fd , EventHandler * handler ) ;
165  static bool disable( List & list , Descriptor fd ) ;
166  static bool remove( List & list , Descriptor fd ) ;
167  void commit() ;
168 
169 private:
170  std::string m_type ;
171  List m_list ;
172  List m_pending_list ;
173  unsigned int m_lock ;
174  bool m_has_garbage ;
175 } ;
176 
177 
178 inline
180 {
181  return Iterator( m_list , false ) ;
182 }
183 
184 inline
186 {
187  return Iterator( m_list , true ) ;
188 }
189 
190 
191 inline
192 GNet::EventHandlerList::Iterator::Iterator( const std::vector<Pair> & v , bool end ) :
193  m_p(end?v.end():v.begin()) ,
194  m_end(v.end())
195 {
196  while( m_p != m_end && (*m_p).second == nullptr )
197  ++m_p ;
198 }
199 
200 inline
201 GNet::EventHandlerList::Iterator & GNet::EventHandlerList::Iterator::operator++()
202 {
203  ++m_p ;
204  while( m_p != m_end && (*m_p).second == nullptr )
205  ++m_p ;
206  return *this ;
207 }
208 
209 inline
210 const GNet::EventHandlerList::Iterator::Pair & GNet::EventHandlerList::Iterator::operator*() const
211 {
212  return *m_p ;
213 }
214 
215 inline
216 GNet::Descriptor GNet::EventHandlerList::Iterator::fd() const
217 {
218  return (*m_p).first ;
219 }
220 
221 inline
222 GNet::EventHandler * GNet::EventHandlerList::Iterator::handler()
223 {
224  return (*m_p).second ;
225 }
226 
227 inline
228 bool GNet::EventHandlerList::Iterator::operator==( const Iterator & other ) const
229 {
230  return m_p == other.m_p ;
231 }
232 
233 inline
234 bool GNet::EventHandlerList::Iterator::operator!=( const Iterator & other ) const
235 {
236  return !(*this == other) ;
237 }
238 
239 #endif
void collectGarbage()
Collects garbage resulting from remove()s.
An abstract interface for handling exceptions thrown out of event-loop callbacks (socket events and t...
Definition: geventhandler.h:44
Iterator begin() const
Returns a forward iterator.
virtual void readEvent()
Called for a read event.
virtual void onException(std::exception &)=0
Called by the event loop when an exception is thrown out of an event loop callback.
A class that encapsulates a network file descriptor and hides knowledge of its o/s-spefific error val...
Definition: gdescriptor.h:37
void lock()
To be called at the start of an begin()/end() iteration if the list might change during the iteration...
virtual void writeEvent()
Called for a write event.
bool contains(Descriptor fd) const
Returns true if the list contains the given file-descriptor.
A base class for classes that handle asynchronous events from the event loop.
Definition: geventhandler.h:78
void add(Descriptor fd, EventHandler *handler)
Adds a file-descriptor/handler pair to the list.
virtual ~EventExceptionHandler()
Destructor.
void unlock()
Called at the end of a begin()/end() iteration to match a call to lock().
Iterator end() const
Returns an end iterator.
An iterator for file-descriptor/handler-function pairs in a GNet::EventHandlerList.
EventHandlerList(const std::string &type)
Constructor.
EventHandler * find(Descriptor fd)
Finds the handler associated with the given file descriptor.
virtual ~EventHandler()
Destructor.
virtual void exceptionEvent()
Called for a socket-exception event.
A class that maps from a file descriptor to an event handler, used in the implemention of classes der...