E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

geventhandlerlist.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2018 Graeme Walker <graeme_walker@users.sourceforge.net>
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 geventhandlerlist.h
19 ///
20
21 #ifndef G_EVENT_HANDLER_LIST__H
22 #define G_EVENT_HANDLER_LIST__H
23
24 #include "gdef.h"
25 #include "gexceptionhandler.h"
26 #include "geventhandler.h"
27 #include "gdescriptor.h"
28 #include <vector>
29 #include <string>
30
31 namespace GNet
32 {
33 class EventHandlerList ;
34 }
35
36 /// \class GNet::EventHandlerList
37 /// A class that maps from a file descriptor to an event handler, used
38 /// in the implemention of classes derived from GNet::EventLoop.
39 ///
40 /// If an event handler is removed from the list while the list is
41 /// being iterated over then the relevant pointer is reset without
42 /// affecting the iteration. The unlock() method does garbage collection
43 /// once the iteration is complete.
44 ///
45 /// If an event handler is added to the list while the list is being
46 /// iterated over then it is added to a pending-list. The pending
47 /// list is added to the main list by unlock() once the iteration
48 /// is complete.
49 ///
50 /// Each event handler can also have an associated exception handler,
51 /// typically a more long-lived object that has the event handler as
52 /// a sub-object. The exception handler is invoked if the event handler
53 /// throws. This is safe even if the exception handler object is
54 /// destroyed by the exception because the exception handler base-class
55 /// destructor uses the disarm() mechanism.
56 ///
57 /// Note that the Descriptor class is actually in two parts for Windows:
58 /// a socket handle (file descriptor) and an event-object handle. The
59 /// event handler list is keyed by the full Descriptor object rather than
60 /// just the socket handle and this allows it to contain event-handling
61 /// objects that are not sockets. See GNet::FutureEvent.
62 ///
63 class GNet::EventHandlerList
64 {
65 public:
66 struct Value /// A tuple for GNet::EventHandlerList.
67 {
68 Descriptor first ;
69 EventHandler * second ;
70 ExceptionHandler * third ;
71 Value() : second(nullptr) , third(nullptr) {}
72 Value( Descriptor fd , EventHandler * p1 , ExceptionHandler * p2 ) : first(fd) , second(p1) , third(p2) {}
73 explicit Value( Descriptor fd ) : first(fd) , second(nullptr) , third(nullptr) {}
74 } ;
75 struct Iterator /// An iterator for GNet::EventHandlerList.
76 {
77 typedef EventHandlerList::Value Value ;
78 Iterator( const std::vector<Value> & , bool ) ;
79 Iterator( std::vector<Value>::const_iterator , std::vector<Value>::const_iterator ) ;
80 Iterator & operator++() ;
81 const Value & operator*() const ;
82 bool operator==( const Iterator & ) const ;
83 bool operator!=( const Iterator & ) const ;
84 Descriptor fd() const ;
85 EventHandler * handler() ;
86 ExceptionHandler * eh() ;
87 void raiseEvent( void (EventHandler::*method)() ) ;
88 void raiseEvent( void (EventHandler::*method)(EventHandler::Reason) , EventHandler::Reason ) ;
89 std::vector<Value>::const_iterator m_p ;
90 std::vector<Value>::const_iterator m_end ;
91 } ;
92 struct Lock /// A raii class to lock and unlock GNet::EventHandlerList.
93 {
94 explicit Lock( EventHandlerList & , bool * invalid_p = nullptr ) ;
95 ~Lock() ;
96 EventHandlerList & m_list ;
97 bool * m_invalid_p ;
98 } ;
99
100 public:
101 explicit EventHandlerList( const std::string & type ) ;
102 ///< Constructor. The type parameter (eg. "read") is used only in
103 ///< debugging messages.
104
105 void add( Descriptor fd , EventHandler * handler , ExceptionHandler * ) ;
106 ///< Adds a file-descriptor/handler tuple to the list.
107
108 void remove( Descriptor fd ) ;
109 ///< Removes a file-descriptor from the list.
110
111 Iterator find( Descriptor fd ) const ;
112 ///< Finds an entry in the list. Returns end() if not found.
113 ///< This ignores any pending changes, ie. descriptors add()ed
114 ///< or remove()d while lock()ed.
115
116 bool contains( Descriptor fd ) const ;
117 ///< Returns true if the list, taking account of any pending
118 ///< changes, contains the given descriptor.
119
120 void lock() ;
121 ///< To be called at the start of an begin()/end() iteration if the
122 ///< list might change during the iteration. Must be paired with
123 ///< unlock().
124
125 bool unlock() ;
126 ///< Called at the end of a begin()/end() iteration to match a call
127 ///< to lock(). Does garbage collection. Returns true if anything
128 ///< might have changed.
129
130 Iterator begin() const ;
131 ///< Returns a forward iterator. Use lock() before iterating.
132
133 Iterator end() const ;
134 ///< Returns an end iterator.
135
136 void disarm( ExceptionHandler * ) ;
137 ///< Resets any matching ExceptionHandler pointers.
138
139 private:
140 typedef std::vector<Value> List ;
141 EventHandlerList( const EventHandlerList & ) ;
142 void operator=( const EventHandlerList & ) ;
143 static void addImp( List & list , Descriptor fd , EventHandler * , ExceptionHandler * ) ;
144 static bool disable( List & list , Descriptor fd ) ;
145 static bool remove( List & list , Descriptor fd ) ;
146 void disarm( List & , ExceptionHandler * ) ;
147 void commitPending() ;
148 void collectGarbage() ;
149
150 private:
151 std::string m_type ;
152 List m_list ;
153 List m_pending_list ;
154 unsigned int m_lock ;
155 bool m_has_garbage ;
156 } ;
157
158 inline
159 GNet::EventHandlerList::Iterator GNet::EventHandlerList::begin() const
160 {
161 return Iterator( m_list , false ) ;
162 }
163
164 inline
165 GNet::EventHandlerList::Iterator GNet::EventHandlerList::end() const
166 {
167 return Iterator( m_list , true ) ;
168 }
169
170 inline
171 GNet::EventHandlerList::Iterator::Iterator( std::vector<Value>::const_iterator p , std::vector<Value>::const_iterator end ) :
172 m_p(p) ,
173 m_end(end)
174 {
175 }
176
177 inline
178 GNet::EventHandlerList::Iterator::Iterator( const std::vector<Value> & v , bool end ) :
179 m_p(end?v.end():v.begin()) ,
180 m_end(v.end())
181 {
182 while( m_p != m_end && (*m_p).second == nullptr )
183 ++m_p ;
184 }
185
186 inline
187 GNet::EventHandlerList::Iterator & GNet::EventHandlerList::Iterator::operator++()
188 {
189 ++m_p ;
190 while( m_p != m_end && (*m_p).second == nullptr )
191 ++m_p ;
192 return *this ;
193 }
194
195 inline
196 const GNet::EventHandlerList::Value & GNet::EventHandlerList::Iterator::operator*() const
197 {
198 return *m_p ;
199 }
200
201 inline
202 GNet::Descriptor GNet::EventHandlerList::Iterator::fd() const
203 {
204 return (*m_p).first ;
205 }
206
207 inline
208 GNet::EventHandler * GNet::EventHandlerList::Iterator::handler()
209 {
210 return (*m_p).second ;
211 }
212
213 inline
214 GNet::ExceptionHandler * GNet::EventHandlerList::Iterator::eh()
215 {
216 return (*m_p).third ;
217 }
218
219 inline
220 bool GNet::EventHandlerList::Iterator::operator==( const Iterator & other ) const
221 {
222 return m_p == other.m_p ;
223 }
224
225 inline
226 bool GNet::EventHandlerList::Iterator::operator!=( const Iterator & other ) const
227 {
228 return !(*this == other) ;
229 }
230
231 #endif
GNet::EventHandlerList::find
Iterator find(Descriptor fd) const
Finds an entry in the list.
Definition: geventhandlerlist.cpp:115
GNet
Network classes.
Definition: gaddress.h:29
GNet::EventHandlerList::begin
Iterator begin() const
Returns a forward iterator. Use lock() before iterating.
Definition: geventhandlerlist.h:159
GNet::Descriptor
A class that encapsulates a network socket file descriptor and an associated windows event handle...
Definition: gdescriptor.h:36
GNet::EventHandlerList::disarm
void disarm(ExceptionHandler *)
Resets any matching ExceptionHandler pointers.
Definition: geventhandlerlist.cpp:100
GNet::EventHandlerList::lock
void lock()
To be called at the start of an begin()/end() iteration if the list might change during the iteration...
Definition: geventhandlerlist.cpp:131
GNet::ExceptionHandler
An abstract interface for handling exceptions thrown out of event-loop callbacks (socket events...
Definition: gexceptionhandler.h:44
GNet::EventHandlerList::unlock
bool unlock()
Called at the end of a begin()/end() iteration to match a call to lock().
Definition: geventhandlerlist.cpp:136
GNet::EventHandlerList::Lock
A raii class to lock and unlock GNet::EventHandlerList.
Definition: geventhandlerlist.h:92
GNet::EventHandlerList::contains
bool contains(Descriptor fd) const
Returns true if the list, taking account of any pending changes, contains the given descriptor...
Definition: geventhandlerlist.cpp:122
geventhandler.h
gexceptionhandler.h
GNet::EventHandler
A base class for classes that handle asynchronous events from the event loop.
Definition: geventhandler.h:47
GNet::EventHandlerList::add
void add(Descriptor fd, EventHandler *handler, ExceptionHandler *)
Adds a file-descriptor/handler tuple to the list.
Definition: geventhandlerlist.cpp:45
gdescriptor.h
GNet::EventHandlerList::end
Iterator end() const
Returns an end iterator.
Definition: geventhandlerlist.h:165
GNet::EventHandlerList::Value
A tuple for GNet::EventHandlerList.
Definition: geventhandlerlist.h:66
GNet::EventHandlerList::Iterator
An iterator for GNet::EventHandlerList.
Definition: geventhandlerlist.h:75
GNet::EventHandlerList::EventHandlerList
EventHandlerList(const std::string &type)
Constructor.
Definition: geventhandlerlist.cpp:38
GNet::EventHandlerList
A class that maps from a file descriptor to an event handler, used in the implemention of classes der...
Definition: geventhandlerlist.h:63