E-MailRelay

gfutureevent.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2024 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 gfutureevent.h
19///
20
21#ifndef G_NET_FUTURE_EVENT_H
22#define G_NET_FUTURE_EVENT_H
23
24#include "gdef.h"
25#include "geventstate.h"
26#include "geventhandler.h"
27#include "gexception.h"
28#include <memory>
29
30 namespace GNet
31{
32 class FutureEvent ;
33 class FutureEventHandler ;
34 class FutureEventImp ;
35}
36
37//| \class GNet::FutureEvent
38/// A FutureEvent object can be used to send a one-shot event between
39/// threads via the event loop, resulting in a call to the relevant
40/// event handler. This is used in the implementation of multi-threaded
41/// asynchronous task classes such as GNet::Task and GNet::Resolver.
42///
43/// The thread-safe trigger function send() is typically called from
44/// a worker thread just before the thread finishes.
45///
46/// Eg:
47/// \code
48/// struct Foo : private FutureEventHandler , private ExceptionHandler
49/// {
50/// Foo() ;
51/// G::Slot::signal<int> m_signal ;
52/// private:
53/// void run( HANDLE ) ;
54/// void onFutureEvent() override ;
55/// FutureEvent m_future_event ;
56/// std::thread m_thread ;
57/// int m_result ;
58/// }
59/// Foo::Foo() :
60/// m_future_event(*this,*this) ,
61/// m_thread(&Foo::run,this,m_future_event.handle())
62/// {
63/// }
64/// void Foo::run( HANDLE h )
65/// {
66/// // this is the worker thread spun off from the ctor
67/// m_result = ... ; // do blocking work
68/// FutureEvent::send( h ) ; // raise 'work complete' event
69/// }
70/// void Foo::onFutureEvent()
71/// {
72/// m_signal.emit( m_result ) ;
73/// }
74/// \endcode
75///
76/// The typical implementation uses a socketpair, with the read socket's
77/// file descriptor registered with the event loop in the normal way
78/// and the socket event handler delegating to the future-event
79/// handler.
80///
81 class GNet::FutureEvent
82{
83 public:
84 G_EXCEPTION( Error , tx("FutureEvent error") )
85
86 FutureEvent( FutureEventHandler & , EventState ) ;
87 ///< Constructor. Installs itself in the event loop.
88
89 ~FutureEvent() ;
90 ///< Destructor.
91
92 HANDLE handle() noexcept ;
93 ///< Extracts a handle that can be passed between threads
94 ///< and used in send(). This should be called once,
95 ///< typically as the worker thread is created.
96
97 static bool send( HANDLE handle , bool close = true ) noexcept ;
98 ///< Pokes an event into the main event loop so that the
99 ///< FutureEventHandler callback is called asynchronously.
100 ///<
101 ///< Should be called exactly once with 'close' true
102 ///< if handle() has been called, typically just before
103 ///< the worker thread finishes.
104 ///<
105 ///< This is safe even if the FutureEvent object has been
106 ///< deleted. Returns true on success.
107
108 static HANDLE createHandle() ;
109 ///< Used by some event loop implementations to create the
110 ///< underlying synchronisation object.
111
112public:
113 FutureEvent( const FutureEvent & ) = delete ;
114 FutureEvent( FutureEvent && ) = delete ;
115 FutureEvent & operator=( const FutureEvent & ) = delete ;
116 FutureEvent & operator=( FutureEvent && ) = delete ;
117
118private:
119 std::unique_ptr<FutureEventImp> m_imp ;
120} ;
121
122//| \class GNet::FutureEventHandler
123/// A callback interface for GNet::FutureEvent.
124///
125 class GNet::FutureEventHandler
126{
127 public:
128 virtual ~FutureEventHandler() = default ;
129 ///< Destructor.
130
131 virtual void onFutureEvent() = 0 ;
132 ///< Callback function that delivers the future event.
133} ;
134
135#endif
GNet::EventState
A lightweight object containing an ExceptionHandler pointer, optional ExceptionSource pointer and opt...
Definition: geventstate.h:131
GNet::FutureEventHandler
A callback interface for GNet::FutureEvent.
Definition: gfutureevent.h:126
GNet::FutureEventHandler::onFutureEvent
virtual void onFutureEvent()=0
Callback function that delivers the future event.
GNet::FutureEventHandler::~FutureEventHandler
virtual ~FutureEventHandler()=default
Destructor.
GNet::FutureEvent
A FutureEvent object can be used to send a one-shot event between threads via the event loop,...
Definition: gfutureevent.h:82
GNet::FutureEvent::FutureEvent
FutureEvent(FutureEventHandler &, EventState)
Constructor. Installs itself in the event loop.
Definition: gfutureevent_unix.cpp:150
GNet::FutureEvent::send
static bool send(HANDLE handle, bool close=true) noexcept
Pokes an event into the main event loop so that the FutureEventHandler callback is called asynchronou...
Definition: gfutureevent_unix.cpp:158
GNet::FutureEvent::handle
HANDLE handle() noexcept
Extracts a handle that can be passed between threads and used in send().
Definition: gfutureevent_unix.cpp:163
GNet::FutureEvent::createHandle
static HANDLE createHandle()
Used by some event loop implementations to create the underlying synchronisation object.
Definition: gfutureevent_win32.cpp:166
GNet::FutureEvent::~FutureEvent
~FutureEvent()
Destructor.
geventhandler.h
geventstate.h
gexception.h
GNet
Network classes.
Definition: gdef.h:1243
G::tx
constexpr const char * tx(const char *p) noexcept
A briefer alternative to G::gettext_noop().
Definition: ggettext.h:84
std
STL namespace.