E-MailRelay

geventloop.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 geventloop.h
19///
20
21#ifndef G_NET_EVENT_LOOP_H
22#define G_NET_EVENT_LOOP_H
23
24#include "gdef.h"
25#include "geventhandler.h"
26#include "geventstate.h"
27#include "gexception.h"
28#include "gdescriptor.h"
29#include "gsignalsafe.h"
30#include <list>
31#include <memory>
32#include <string>
33
34 namespace GNet
35{
36 class EventLoop ;
37}
38
39//| \class GNet::EventLoop
40/// An abstract base class for a singleton that keeps track of open sockets
41/// and their associated handlers. Derived classes are used to implement
42/// different event loops, such as select() or WaitForMultipleObjects().
43///
44/// In practice sockets should be added and removed from the class by
45/// calling GNet::Socket::addReadHandler() and friends rather than by calling
46/// EventLoop::addRead() etc. so that the event handle is passed correctly
47/// when running on windows.
48///
49/// The class has a static member for finding an instance, but instances
50/// are not created automatically.
51///
52/// \code
53/// int main()
54/// {
55/// auto event_loop = GNet::EventLoop::create() ;
56/// App app ; // EventLoop::instance().addRead() etc.
57/// event_loop->run() ;
58/// return 0 ;
59/// }
60/// \endcode
61///
62 class GNet::EventLoop
63{
64 public:
65 G_EXCEPTION( Error , tx("event loop error") )
66 G_EXCEPTION( NoInstance , tx("no event loop instance") )
67 G_EXCEPTION( Overflow , tx("event loop overflow") )
68
69 protected:
70 EventLoop() ;
71 ///< Constructor.
72
73 public:
74 static std::unique_ptr<EventLoop> create() ;
75 ///< A factory method which creates an instance of a derived
76 ///< class on the heap. Throws on error.
77
78 static EventLoop & instance() ;
79 ///< Returns a reference to an instance of the class,
80 ///< if any. Throws if none. Does not do any instantiation
81 ///< itself.
82
83 static EventLoop * ptr() noexcept ;
84 ///< Returns a pointer to an instance of the class, if any.
85 ///< Returns the null pointer if none.
86
87 static bool exists() ;
88 ///< Returns true if an instance exists.
89
90 static void stop( const G::SignalSafe & ) ;
91 ///< Calls quit() on instance().
92
93 virtual ~EventLoop() ;
94 ///< Destructor.
95
96 virtual std::string run() = 0 ;
97 ///< Runs the main event loop. Returns a quit() reason,
98 ///< if any.
99
100 virtual bool running() const = 0 ;
101 ///< Returns true if called from within run().
102
103 virtual void quit( const std::string & reason ) = 0 ;
104 ///< Causes run() to return (once the call stack has
105 ///< unwound). If there are multiple quit()s before
106 ///< run() returns then the latest reason is used.
107
108 virtual void quit( const G::SignalSafe & ) = 0 ;
109 ///< A signal-safe overload to quit() the event loop.
110
111 virtual void addRead( Descriptor fd , EventHandler & , EventState ) = 0 ;
112 ///< Adds the given event source descriptor and associated
113 ///< handler to the read list.
114 ///< See also Socket::addReadHandler().
115
116 virtual void addWrite( Descriptor fd , EventHandler & , EventState ) = 0 ;
117 ///< Adds the given event source descriptor and associated
118 ///< handler to the write list.
119 ///< See also Socket::addWriteHandler().
120
121 virtual void addOther( Descriptor fd , EventHandler & , EventState ) = 0 ;
122 ///< Adds the given event source descriptor and associated
123 ///< handler to the exception list.
124 ///< See also Socket::addOtherHandler().
125
126 virtual void dropRead( Descriptor fd ) noexcept = 0 ;
127 ///< Removes the given event descriptor from the
128 ///< list of read sources.
129 ///< See also Socket::dropReadHandler().
130
131 virtual void dropWrite( Descriptor fd ) noexcept = 0 ;
132 ///< Removes the given event descriptor from the
133 ///< list of write sources.
134 ///< See also Socket::dropWriteHandler().
135
136 virtual void dropOther( Descriptor fd ) noexcept = 0 ;
137 ///< Removes the given event descriptor from the
138 ///< list of other-event sources.
139 ///< See also Socket::dropOtherHandler().
140
141 virtual void drop( Descriptor fd ) noexcept = 0 ;
142 ///< Removes the given event descriptor from the
143 ///< event loop as the EventHandler is being
144 ///< destructed.
145
146 virtual void disarm( ExceptionHandler * ) noexcept = 0 ;
147 ///< Used to prevent the given interface from being used,
148 ///< typically called from the ExceptionHandler
149 ///< destructor.
150
151 public:
152 EventLoop( const EventLoop & ) = delete ;
153 EventLoop( EventLoop && ) = delete ;
154 EventLoop & operator=( const EventLoop & ) = delete ;
155 EventLoop & operator=( EventLoop && ) = delete ;
156
157 private:
158 static EventLoop * m_this ;
159} ;
160
161#endif
GNet::Descriptor
A class that encapsulates a network socket file descriptor and an associated windows event handle.
Definition: gdescriptor.h:37
GNet::EventHandler
A base class for classes that have a file descriptor and handle asynchronous events from the event lo...
Definition: geventhandler.h:48
GNet::EventLoop
An abstract base class for a singleton that keeps track of open sockets and their associated handlers...
Definition: geventloop.h:63
GNet::EventLoop::~EventLoop
virtual ~EventLoop()
Destructor.
Definition: geventloop.cpp:34
GNet::EventLoop::dropWrite
virtual void dropWrite(Descriptor fd) noexcept=0
Removes the given event descriptor from the list of write sources.
GNet::EventLoop::running
virtual bool running() const =0
Returns true if called from within run().
GNet::EventLoop::drop
virtual void drop(Descriptor fd) noexcept=0
Removes the given event descriptor from the event loop as the EventHandler is being destructed.
GNet::EventLoop::create
static std::unique_ptr< EventLoop > create()
A factory method which creates an instance of a derived class on the heap.
Definition: geventloop_epoll.cpp:108
GNet::EventLoop::quit
virtual void quit(const G::SignalSafe &)=0
A signal-safe overload to quit() the event loop.
GNet::EventLoop::stop
static void stop(const G::SignalSafe &)
Calls quit() on instance().
Definition: geventloop.cpp:58
GNet::EventLoop::dropRead
virtual void dropRead(Descriptor fd) noexcept=0
Removes the given event descriptor from the list of read sources.
GNet::EventLoop::ptr
static EventLoop * ptr() noexcept
Returns a pointer to an instance of the class, if any.
Definition: geventloop.cpp:40
GNet::EventLoop::exists
static bool exists()
Returns true if an instance exists.
Definition: geventloop.cpp:52
GNet::EventLoop::disarm
virtual void disarm(ExceptionHandler *) noexcept=0
Used to prevent the given interface from being used, typically called from the ExceptionHandler destr...
GNet::EventLoop::quit
virtual void quit(const std::string &reason)=0
Causes run() to return (once the call stack has unwound).
GNet::EventLoop::run
virtual std::string run()=0
Runs the main event loop.
GNet::EventLoop::addWrite
virtual void addWrite(Descriptor fd, EventHandler &, EventState)=0
Adds the given event source descriptor and associated handler to the write list.
GNet::EventLoop::instance
static EventLoop & instance()
Returns a reference to an instance of the class, if any.
Definition: geventloop.cpp:45
GNet::EventLoop::EventLoop
EventLoop()
Constructor.
Definition: geventloop.cpp:28
GNet::EventLoop::dropOther
virtual void dropOther(Descriptor fd) noexcept=0
Removes the given event descriptor from the list of other-event sources.
GNet::EventLoop::addRead
virtual void addRead(Descriptor fd, EventHandler &, EventState)=0
Adds the given event source descriptor and associated handler to the read list.
GNet::EventLoop::addOther
virtual void addOther(Descriptor fd, EventHandler &, EventState)=0
Adds the given event source descriptor and associated handler to the exception list.
GNet::EventState
A lightweight object containing an ExceptionHandler pointer, optional ExceptionSource pointer and opt...
Definition: geventstate.h:131
GNet::ExceptionHandler
An abstract interface for handling exceptions thrown out of event-loop callbacks (socket/future event...
Definition: gexceptionhandler.h:44
G::SignalSafe
An empty structure that is used to indicate a signal-safe, reentrant implementation.
Definition: gsignalsafe.h:37
gdescriptor.h
geventhandler.h
geventstate.h
gexception.h
gsignalsafe.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