E-MailRelay
gexceptionsink.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 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 gexceptionsink.h
19///
20
21#ifndef G_NET_EXCEPTION_SINK_H
22#define G_NET_EXCEPTION_SINK_H
23
24#include "gdef.h"
25#include "gexceptionhandler.h"
26#include "gexceptionsource.h"
27#include <exception>
28#include <typeinfo>
29
30namespace GNet
31{
32 class ExceptionSink ;
33 class ExceptionSinkUnbound ;
34}
35
36//| \class GNet::ExceptionSink
37/// A tuple containing an ExceptionHandler interface pointer and
38/// a bound 'exception source' pointer.
39///
40/// The EventHandlerList and TimerList classes associate an
41/// event handler and ExceptionSink with each event source
42/// (file descriptor or timer). If the event handler throws
43/// an exception then the associated ExceptionHandler's
44/// onException() method is called, via ExceptionSink::call().
45///
46/// An onException() implementation normally just rethrows the
47/// exception to terminate the event loop, but sometimes the
48/// exception can be handled less drastically, perhaps by
49/// deleting the object identified as the exception source.
50///
51/// For example, Server objects create and contain ServerPeer
52/// objects:
53///
54/// \code
55/// class ServerPeer : public ExceptionSource { ... } ;
56/// class Server : private ExceptionHandler
57/// {
58/// void init() { m_peer = newServerPeer(...) ; }
59/// void onException( ExceptionSource * source ... ) override
60/// {
61/// assert( source == m_peer ) ;
62/// delete source ;
63/// }
64/// ServerPeer * m_peer ;
65/// } ;
66/// \endcode
67///
68/// The ExceptionSinkUnbound class is used as syntactic sugar
69/// to force factory methods to supply an ExceptionSource
70/// pointer that points to the most-derived ServerPeer class.
71///
72/// \code
73/// class FooServerPeer : public ServerPeer
74/// {
75/// public:
76/// FooServerPeer * newServerPeer( ExceptionSinkUnbound esu , ... ) override
77/// {
78/// return new FooServerPeer( esu , ... ) ;
79/// }
80/// private:
81/// FooServerPeer( ExceptionSinkUnbound esu , ... ) :
82/// ServerPeer( esu.bind(this) , ... )
83/// {
84/// }
85/// } ;
86/// \endcode
87///
88/// So then the ServerPeer constructor has a bound ExceptionSink that
89/// it can pass to its timers etc. and to the event-handler list:
90///
91/// \code
92/// ServerPeer::ServerPeer( ExceptionSink es , ... ) :
93/// m_timer(..., es)
94/// {
95/// EventHandlerList::instance().add( es , ... ) ;
96/// }
97/// \endcode
98///
100{
101public:
102 enum class Type
103 {
104 Null , // eh() is nullptr, call() does nothing
105 Rethrow , // rethrows
106 Log // logs an error with G_ERROR
107 } ;
108
109 explicit ExceptionSink( Type = Type::Rethrow , ExceptionSource * source = nullptr ) noexcept ;
110 ///< Constructor.
111
112 ExceptionSink( ExceptionHandler & eh , ExceptionSource * source ) noexcept ;
113 ///< Constructor. The ExceptionHandler reference must
114 ///< remain valid as the ExceptionSink is copied around.
115
116 ExceptionSink( ExceptionHandler * eh , ExceptionSource * source ) noexcept ;
117 ///< Constructor. The ExceptionHandler pointer must
118 ///< remain valid as the ExceptionSink is copied around.
119
120 ExceptionSink( std::nullptr_t , ExceptionSource * ) = delete ;
121 ///< Deleted override to prohibit a null ExceptionHandler.
122
123 ExceptionHandler * eh() const noexcept ;
124 ///< Returns the exception handler pointer.
125
126 ExceptionSource * esrc() const noexcept ;
127 ///< Returns the exception source pointer.
128
129 void call( std::exception & e , bool done ) ;
130 ///< Calls the exception handler's onException() method.
131 ///< Used by EventHandlerList and TimerList. Exceptions
132 ///< thrown out of the onException() implementation are
133 ///< allowed to propagate.
134
135 void reset() noexcept ;
136 ///< Resets the pointers.
137
138 bool set() const noexcept ;
139 ///< Returns true if eh() is not null.
140
141private:
142 ExceptionHandler * m_eh ;
143 ExceptionSource * m_esrc{nullptr} ;
144} ;
145
146//| \class GNet::ExceptionSinkUnbound
147/// A potential ExceptionSink that is realised by bind()ing an
148/// exception source pointer. This is used in factory functions
149/// such as GNet::Server::newPeer() where the container that
150/// uses the factory function to create a containee needs to
151/// know which containee a subsequent exception came from.
152///
154{
155public:
156 explicit ExceptionSinkUnbound( ExceptionHandler * eh ) ;
157 ///< Constructor.
158
159 explicit ExceptionSinkUnbound( ExceptionHandler & eh ) ;
160 ///< Constructor.
161
162 ExceptionSink bind( ExceptionSource * source ) const ;
163 ///< Returns a sink object with the source pointer set.
164
165private:
166 ExceptionHandler * m_eh ;
167} ;
168
169#endif
An abstract interface for handling exceptions thrown out of event-loop callbacks (socket/future event...
A potential ExceptionSink that is realised by bind()ing an exception source pointer.
ExceptionSinkUnbound(ExceptionHandler *eh)
Constructor.
ExceptionSink bind(ExceptionSource *source) const
Returns a sink object with the source pointer set.
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
ExceptionHandler * eh() const noexcept
Returns the exception handler pointer.
ExceptionSource * esrc() const noexcept
Returns the exception source pointer.
ExceptionSink(Type=Type::Rethrow, ExceptionSource *source=nullptr) noexcept
Constructor.
void call(std::exception &e, bool done)
Calls the exception handler's onException() method.
void reset() noexcept
Resets the pointers.
bool set() const noexcept
Returns true if eh() is not null.
ExceptionSink(std::nullptr_t, ExceptionSource *)=delete
Deleted override to prohibit a null ExceptionHandler.
A mixin base class that identifies the source of an exception when delivered to GNet::ExceptionHandle...
Network classes.
Definition: gdef.h:1115