E-MailRelay
geventloop.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 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 "gexceptionsink.h"
27#include "gexception.h"
28#include "gdescriptor.h"
29#include "gsignalsafe.h"
30#include <list>
31#include <memory>
32#include <string>
33
34namespace 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///
53{
54public:
55 G_EXCEPTION( Error , "failed to initialise the event loop" ) ;
56 G_EXCEPTION( NoInstance , "no event loop instance" ) ;
57 G_EXCEPTION( Overflow , "event loop overflow" ) ;
58
59protected:
60 EventLoop() ;
61 ///< Constructor.
62
63public:
64 static std::unique_ptr<EventLoop> create() ;
65 ///< A factory method which creates an instance of a derived
66 ///< class on the heap. Throws on error.
67
68 static EventLoop & instance() ;
69 ///< Returns a reference to an instance of the class,
70 ///< if any. Throws if none. Does not do any instantiation
71 ///< itself.
72
73 static EventLoop * ptr() noexcept ;
74 ///< Returns a pointer to an instance of the class, if any.
75 ///< Returns the null pointer if none.
76
77 static bool exists() ;
78 ///< Returns true if an instance exists.
79
80 static void stop( const G::SignalSafe & ) ;
81 ///< Calls quit() on instance().
82
83 virtual ~EventLoop() ;
84 ///< Destructor.
85
86 virtual std::string run() = 0 ;
87 ///< Runs the main event loop. Returns a quit() reason,
88 ///< if any.
89
90 virtual bool running() const = 0 ;
91 ///< Returns true if called from within run().
92
93 virtual void quit( const std::string & reason ) = 0 ;
94 ///< Causes run() to return (once the call stack has
95 ///< unwound). If there are multiple quit()s before
96 ///< run() returns then the latest reason is used.
97
98 virtual void quit( const G::SignalSafe & ) = 0 ;
99 ///< A signal-safe overload to quit() the event loop.
100
101 virtual void addRead( Descriptor fd , EventHandler & , ExceptionSink ) = 0 ;
102 ///< Adds the given event source descriptor and associated
103 ///< handler to the read list.
104 ///< See also Socket::addReadHandler().
105
106 virtual void addWrite( Descriptor fd , EventHandler & , ExceptionSink ) = 0 ;
107 ///< Adds the given event source descriptor and associated
108 ///< handler to the write list.
109 ///< See also Socket::addWriteHandler().
110
111 virtual void addOther( Descriptor fd , EventHandler & , ExceptionSink ) = 0 ;
112 ///< Adds the given event source descriptor and associated
113 ///< handler to the exception list.
114 ///< See also Socket::addOtherHandler().
115
116 virtual void dropRead( Descriptor fd ) noexcept = 0 ;
117 ///< Removes the given event source descriptor from the
118 ///< list of read sources.
119 ///< See also Socket::dropReadHandler().
120
121 virtual void dropWrite( Descriptor fd ) noexcept = 0 ;
122 ///< Removes the given event source descriptor from the
123 ///< list of write sources.
124 ///< See also Socket::dropWriteHandler().
125
126 virtual void dropOther( Descriptor fd ) noexcept = 0 ;
127 ///< Removes the given event source descriptor from the
128 ///< list of exception sources.
129 ///< See also Socket::dropOtherHandler().
130
131 virtual void disarm( ExceptionHandler * ) noexcept = 0 ;
132 ///< Used to prevent the given interface from being used,
133 ///< typically called from the ExceptionHandler
134 ///< destructor.
135
136public:
137 EventLoop( const EventLoop & ) = delete ;
138 EventLoop( EventLoop && ) = delete ;
139 void operator=( const EventLoop & ) = delete ;
140 void operator=( EventLoop && ) = delete ;
141
142private:
143 static EventLoop * m_this ;
144} ;
145
146#endif
A class that encapsulates a network socket file descriptor and an associated windows event handle.
Definition: gdescriptor.h:37
A base class for classes that handle asynchronous events from the event loop.
Definition: geventhandler.h:48
An abstract base class for a singleton that keeps track of open sockets and their associated handlers...
Definition: geventloop.h:53
virtual ~EventLoop()
Destructor.
Definition: geventloop.cpp:36
virtual void dropWrite(Descriptor fd) noexcept=0
Removes the given event source descriptor from the list of write sources.
virtual bool running() const =0
Returns true if called from within run().
static std::unique_ptr< EventLoop > create()
A factory method which creates an instance of a derived class on the heap.
virtual void quit(const G::SignalSafe &)=0
A signal-safe overload to quit() the event loop.
static void stop(const G::SignalSafe &)
Calls quit() on instance().
Definition: geventloop.cpp:59
virtual void dropRead(Descriptor fd) noexcept=0
Removes the given event source descriptor from the list of read sources.
static EventLoop * ptr() noexcept
Returns a pointer to an instance of the class, if any.
Definition: geventloop.cpp:42
virtual void addOther(Descriptor fd, EventHandler &, ExceptionSink)=0
Adds the given event source descriptor and associated handler to the exception list.
static bool exists()
Returns true if an instance exists.
Definition: geventloop.cpp:54
virtual void disarm(ExceptionHandler *) noexcept=0
Used to prevent the given interface from being used, typically called from the ExceptionHandler destr...
virtual void quit(const std::string &reason)=0
Causes run() to return (once the call stack has unwound).
virtual void addWrite(Descriptor fd, EventHandler &, ExceptionSink)=0
Adds the given event source descriptor and associated handler to the write list.
virtual std::string run()=0
Runs the main event loop.
static EventLoop & instance()
Returns a reference to an instance of the class, if any.
Definition: geventloop.cpp:47
virtual void addRead(Descriptor fd, EventHandler &, ExceptionSink)=0
Adds the given event source descriptor and associated handler to the read list.
EventLoop()
Constructor.
Definition: geventloop.cpp:28
virtual void dropOther(Descriptor fd) noexcept=0
Removes the given event source descriptor from the list of exception sources.
An abstract interface for handling exceptions thrown out of event-loop callbacks (socket/future event...
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
An empty structure that is used to indicate a signal-safe, reentrant implementation.
Definition: gsignalsafe.h:37
Network classes.
Definition: gdef.h:1115