Horizon Official Technical Documentation
Horizon::Networking::NetworkThread< SocketType > Class Template Referenceabstract

A Network Thread object that handles a number of sockets. More...

#include <NetworkThread.hpp>

Public Member Functions

 NetworkThread ()
 
virtual ~NetworkThread ()
 Destructor of the network thread, performs a clean network finalisation routine before deleting. More...
 
virtual void finalize ()
 Halts the IO Service and marks the network thread as stopped. More...
 
void join ()
 
virtual bool start (int segment_number=1)
 Initializes the network thread and runs. More...
 
virtual void add_socket (std::shared_ptr< SocketType > sock)
 Adds a new socket to a queue that is processed frequently within this network thread. More...
 
std::shared_ptr< tcp::socket > get_new_socket ()
 Gets a socket for a new connection. More...
 
int32_t connection_count () const
 Gets the total number of network connections or sockets handled by this network thread. More...
 
bool is_finalizing ()
 Issues the status of network thread whether it is finalizing or not. More...
 

Protected Member Functions

virtual void run ()
 Run the I/O Service loop within this network thread. More...
 
virtual void on_socket_removed (std::shared_ptr< SocketType > sock)=0
 
virtual void on_socket_added (std::shared_ptr< SocketType > sock)=0
 
virtual void update ()
 Updates the network thread and schedules a recursive call to itself. More...
 
virtual void add_new_sockets ()
 Processess the new socket queue. More...
 

Protected Attributes

SocketContainer _active_sockets
 

Private Types

typedef std::vector< std::shared_ptr< SocketType > > SocketContainer
 

Private Attributes

int _segment_number {1}
 
std::atomic< int32_t > _connections
 
std::atomic< bool > _finalizing
 
std::unique_ptr< std::thread > _thread
 
SocketContainer _new_socket_queue
 
std::mutex _new_socket_queue_lock
 
boost::asio::io_context _io_context
 
boost::asio::deadline_timer _update_timer
 

Detailed Description

template<class SocketType>
class Horizon::Networking::NetworkThread< SocketType >

A Network Thread object that handles a number of sockets.

Sockets are moved into the thread by SocketMgr, once accepted or connected. Once started, the object blocks to handle I/O events and requires explicit stopping.

Member Typedef Documentation

◆ SocketContainer

template<class SocketType >
typedef std::vector<std::shared_ptr<SocketType> > Horizon::Networking::NetworkThread< SocketType >::SocketContainer
private

Constructor & Destructor Documentation

◆ NetworkThread()

template<class SocketType >
Horizon::Networking::NetworkThread< SocketType >::NetworkThread ( )
inline
60 {
61 // Constructor
62 }
std::atomic< int32_t > _connections
Definition: NetworkThread.hpp:237
boost::asio::deadline_timer _update_timer
Definition: NetworkThread.hpp:247
std::atomic< bool > _finalizing
Definition: NetworkThread.hpp:238
boost::asio::io_context _io_context
Definition: NetworkThread.hpp:246

◆ ~NetworkThread()

template<class SocketType >
virtual Horizon::Networking::NetworkThread< SocketType >::~NetworkThread ( )
inlinevirtual

Destructor of the network thread, performs a clean network finalisation routine before deleting.

69 {
70 finalize();
71 }
virtual void finalize()
Halts the IO Service and marks the network thread as stopped.
Definition: NetworkThread.hpp:76

References Horizon::Networking::NetworkThread< SocketType >::finalize().

+ Here is the call graph for this function:

Member Function Documentation

◆ add_new_sockets()

template<class SocketType >
virtual void Horizon::Networking::NetworkThread< SocketType >::add_new_sockets ( )
inlineprotectedvirtual

Processess the new socket queue.

This method is responsible for - 1) Processing the entire list of new sockets and clearing it on every call. 2) removing / closing new sockets that are not open. 3) Starting the new socket once added to the container. (

See also
Socket<SocketType>::start())
207 {
208 if (is_finalizing())
209 return;
210
211 std::lock_guard<std::mutex> lock(_new_socket_queue_lock);
212
213 if (_new_socket_queue.empty())
214 return;
215
216 for (std::shared_ptr<SocketType> sock : _new_socket_queue) {
217 if (sock->is_open()) {
218 _active_sockets.push_back(sock);
219 // Start receiving from the socket.
220 sock->start();
221
222 on_socket_added(sock);
223
224 ++_connections; // Increment network connections.
225
226 HLog(trace) << "A new socket has been added to network thread " << (void *) (_thread.get()) << " (Connections: " << _connections << ")";
227 }
228 }
229
230 _new_socket_queue.clear();
231 }
#define HLog(type)
Definition: Logger.hpp:122
virtual void on_socket_added(std::shared_ptr< SocketType > sock)=0
SocketContainer _new_socket_queue
Definition: NetworkThread.hpp:242
SocketContainer _active_sockets
Definition: NetworkThread.hpp:234
std::mutex _new_socket_queue_lock
Definition: NetworkThread.hpp:244
std::unique_ptr< std::thread > _thread
Definition: NetworkThread.hpp:240
bool is_finalizing()
Issues the status of network thread whether it is finalizing or not.
Definition: NetworkThread.hpp:136

References HLog.

Referenced by Horizon::Networking::NetworkThread< SocketType >::update().

+ Here is the caller graph for this function:

◆ add_socket()

template<class SocketType >
virtual void Horizon::Networking::NetworkThread< SocketType >::add_socket ( std::shared_ptr< SocketType >  sock)
inlinevirtual

Adds a new socket to a queue that is processed frequently within this network thread.

The method update() is called regularly to add new sockets to the thread's active socket list.

111 {
112 std::lock_guard<std::mutex> lock(_new_socket_queue_lock);
113
114 _new_socket_queue.push_back(sock); // Add socket to queue.
115 }

References Horizon::Networking::NetworkThread< SocketType >::_new_socket_queue, and Horizon::Networking::NetworkThread< SocketType >::_new_socket_queue_lock.

◆ connection_count()

template<class SocketType >
int32_t Horizon::Networking::NetworkThread< SocketType >::connection_count ( ) const
inline

Gets the total number of network connections or sockets handled by this network thread.

Returns
total number of connections in this network thread.
130{ return _connections; }

References Horizon::Networking::NetworkThread< SocketType >::_connections.

◆ finalize()

template<class SocketType >
virtual void Horizon::Networking::NetworkThread< SocketType >::finalize ( )
inlinevirtual

◆ get_new_socket()

template<class SocketType >
std::shared_ptr< tcp::socket > Horizon::Networking::NetworkThread< SocketType >::get_new_socket ( )
inline

Gets a socket for a new connection.

This method is used as a socket factory in AsyncAcceptor and Connector classes. Once a socket is accepted or connected, its ownership is moved into a network thread.

Returns
a new shared pointer to a tcp::socket.
123{ return std::make_shared<tcp::socket>(_io_context); }

References Horizon::Networking::NetworkThread< SocketType >::_io_context.

◆ is_finalizing()

template<class SocketType >
bool Horizon::Networking::NetworkThread< SocketType >::is_finalizing ( )
inline

Issues the status of network thread whether it is finalizing or not.

Returns
boolean finalizing of the network thread status.
136{ return _finalizing; }

References Horizon::Networking::NetworkThread< SocketType >::_finalizing.

◆ join()

template<class SocketType >
void Horizon::Networking::NetworkThread< SocketType >::join ( )
inline
82 {
83 try {
84 _thread->join();
85 } catch (std::system_error &error) {
86 HLog(error) << "Error joining network thread2: " << error.what();
87 }
88 }

References Horizon::Networking::NetworkThread< SocketType >::_thread, and HLog.

◆ on_socket_added()

template<class SocketType >
virtual void Horizon::Networking::NetworkThread< SocketType >::on_socket_added ( std::shared_ptr< SocketType >  sock)
protectedpure virtual

◆ on_socket_removed()

template<class SocketType >
virtual void Horizon::Networking::NetworkThread< SocketType >::on_socket_removed ( std::shared_ptr< SocketType >  sock)
protectedpure virtual

◆ run()

template<class SocketType >
virtual void Horizon::Networking::NetworkThread< SocketType >::run ( )
inlineprotectedvirtual

Run the I/O Service loop within this network thread.

Before running, this method gives the I/O service some work by asynchronously running a deadline timer on

See also
update()

Reimplemented in Horizon::Auth::AuthNetworkThread, Horizon::Char::CharNetworkThread, and Horizon::Zone::ZoneNetworkThread.

144 {
145 _update_timer.expires_from_now(boost::posix_time::microseconds(500));
146 _update_timer.async_wait(std::bind(&NetworkThread<SocketType>::update, this));
147
148 _io_context.run();
149
150 _new_socket_queue.clear();
151 _active_sockets.clear();
152 }
virtual void update()
Updates the network thread and schedules a recursive call to itself.
Definition: NetworkThread.hpp:163

References Horizon::Networking::NetworkThread< SocketType >::_active_sockets, Horizon::Networking::NetworkThread< SocketType >::_io_context, Horizon::Networking::NetworkThread< SocketType >::_new_socket_queue, and Horizon::Networking::NetworkThread< SocketType >::_update_timer.

Referenced by Horizon::Auth::AuthNetworkThread::run(), Horizon::Char::CharNetworkThread::run(), Horizon::Zone::ZoneNetworkThread::run(), and Horizon::Networking::NetworkThread< SocketType >::start().

+ Here is the caller graph for this function:

◆ start()

template<class SocketType >
virtual bool Horizon::Networking::NetworkThread< SocketType >::start ( int  segment_number = 1)
inlinevirtual

Initializes the network thread and runs.

Returns
true on success, false if thread is a nullptr.

Reimplemented in Horizon::Auth::AuthNetworkThread, Horizon::Char::CharNetworkThread, and Horizon::Zone::ZoneNetworkThread.

95 {
96 if (_thread != nullptr)
97 return false;
98
99 _segment_number = segment_number;
100 _thread.reset(new std::thread(&NetworkThread::run, this));
101 return true;
102 }
virtual void run()
Run the I/O Service loop within this network thread.
Definition: NetworkThread.hpp:143
int _segment_number
Definition: NetworkThread.hpp:236

References Horizon::Networking::NetworkThread< SocketType >::_segment_number, Horizon::Networking::NetworkThread< SocketType >::_thread, and Horizon::Networking::NetworkThread< SocketType >::run().

+ Here is the call graph for this function:

◆ update()

template<class SocketType >
virtual void Horizon::Networking::NetworkThread< SocketType >::update ( )
inlineprotectedvirtual

Updates the network thread and schedules a recursive call to itself.

This method is responsible for the following tasks - 1) Issuing a routine to process the new sockets queue. 2) Closes sockets that cannot be updated.

See also
Socket<SocketType>::update()

Reimplemented in Horizon::Auth::AuthNetworkThread, Horizon::Char::CharNetworkThread, and Horizon::Zone::ZoneNetworkThread.

164 {
165 _update_timer.expires_from_now(boost::posix_time::microseconds(500));
166 _update_timer.async_wait(std::bind(&NetworkThread<SocketType>::update, this));
167
169
170 // The following code removes all non-active from the active sockets list by shifting all
171 // active sockets to the left and then erasing the extra
172 _active_sockets.erase(std::remove_if(_active_sockets.begin(), _active_sockets.end(),
173 [this] (std::shared_ptr<SocketType> sock)
174 {
175 if (!sock->update() || is_finalizing()) {
176
177 if (sock->is_open())
178 sock->close_socket();
179
180 on_socket_removed(sock);
181
182 --_connections;
183
184 HLog(info) << "Socket closed in networking thread " << (void *) (_thread.get()) << " (Connections: " << _connections << ")";
185
186 return true;
187 }
188
189 return false;
190 }), _active_sockets.end());
191
192 if (is_finalizing()) {
193 _io_context.stop();
194 _finalizing.exchange(false);
195 HLog(info) << "Network thread " << (void *) (_thread.get()) << " has been finalized.";
196 }
197 }
virtual void add_new_sockets()
Processess the new socket queue.
Definition: NetworkThread.hpp:206

References Horizon::Networking::NetworkThread< SocketType >::_active_sockets, Horizon::Networking::NetworkThread< SocketType >::_update_timer, and Horizon::Networking::NetworkThread< SocketType >::add_new_sockets().

Referenced by Horizon::Auth::AuthNetworkThread::update(), Horizon::Char::CharNetworkThread::update(), and Horizon::Zone::ZoneNetworkThread::update().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ _active_sockets

◆ _connections

template<class SocketType >
std::atomic<int32_t> Horizon::Networking::NetworkThread< SocketType >::_connections
private

◆ _finalizing

◆ _io_context

template<class SocketType >
boost::asio::io_context Horizon::Networking::NetworkThread< SocketType >::_io_context
private

◆ _new_socket_queue

◆ _new_socket_queue_lock

template<class SocketType >
std::mutex Horizon::Networking::NetworkThread< SocketType >::_new_socket_queue_lock
private

◆ _segment_number

template<class SocketType >
int Horizon::Networking::NetworkThread< SocketType >::_segment_number {1}
private

◆ _thread

template<class SocketType >
std::unique_ptr<std::thread> Horizon::Networking::NetworkThread< SocketType >::_thread
private

◆ _update_timer

template<class SocketType >
boost::asio::deadline_timer Horizon::Networking::NetworkThread< SocketType >::_update_timer
private

The documentation for this class was generated from the following file: