TrinityCore
Loading...
Searching...
No Matches
NetworkThread.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef TRINITYCORE_NETWORK_THREAD_H
19#define TRINITYCORE_NETWORK_THREAD_H
20
21#include "Containers.h"
22#include "DeadlineTimer.h"
23#include "Define.h"
24#include "Errors.h"
25#include "IoContext.h"
26#include "Log.h"
27#include "Socket.h"
28#include "Timer.h"
29#include <boost/asio/ip/tcp.hpp>
30#include <atomic>
31#include <chrono>
32#include <memory>
33#include <mutex>
34#include <set>
35#include <thread>
36
37namespace Trinity::Net
38{
39template<class SocketType>
41{
42public:
47
48 NetworkThread(NetworkThread const&) = delete;
52
54 {
55 Stop();
56 if (_thread)
57 Wait();
58 }
59
60 void Stop()
61 {
62 _stopped = true;
64 }
65
66 bool Start()
67 {
68 if (_thread)
69 return false;
70
71 _thread = std::make_unique<std::thread>(&NetworkThread::Run, this);
72 return true;
73 }
74
75 void Wait()
76 {
78
79 _thread->join();
80 _thread = nullptr;
81 }
82
84 {
85 return _connections;
86 }
87
88 virtual void AddSocket(std::shared_ptr<SocketType> sock)
89 {
90 std::lock_guard<std::mutex> lock(_newSocketsLock);
91
93 SocketAdded(_newSockets.emplace_back(std::move(sock)));
94 }
95
97
98protected:
99 virtual void SocketAdded(std::shared_ptr<SocketType> const& /*sock*/) { }
100 virtual void SocketRemoved(std::shared_ptr<SocketType> const& /*sock*/) { }
101
103 {
104 std::lock_guard<std::mutex> lock(_newSocketsLock);
105
106 if (_newSockets.empty())
107 return;
108
109 for (std::shared_ptr<SocketType>& sock : _newSockets)
110 {
111 if (!sock->IsOpen())
112 {
113 SocketRemoved(sock);
114 --_connections;
115 }
116 else
117 _sockets.emplace_back(std::move(sock));
118 }
119
120 _newSockets.clear();
121 }
122
123 void Run()
124 {
125 TC_LOG_DEBUG("misc", "Network Thread Starting");
126
127 _updateTimer.expires_after(1ms);
128 _updateTimer.async_wait([this](boost::system::error_code const&) { Update(); });
129 _ioContext.run();
130
131 TC_LOG_DEBUG("misc", "Network Thread exits");
132 _newSockets.clear();
133 _sockets.clear();
134 }
135
136 void Update()
137 {
138 if (_stopped)
139 return;
140
141 _updateTimer.expires_after(1ms);
142 _updateTimer.async_wait([this](boost::system::error_code const&) { Update(); });
143
145
146 Trinity::Containers::EraseIf(_sockets, [this](std::shared_ptr<SocketType> const& sock)
147 {
148 if (!sock->Update())
149 {
150 if (sock->IsOpen())
151 sock->CloseSocket();
152
153 this->SocketRemoved(sock);
154
155 --this->_connections;
156 return true;
157 }
158
159 return false;
160 });
161 }
162
163private:
164 typedef std::vector<std::shared_ptr<SocketType>> SocketContainer;
165
166 std::atomic<int32> _connections;
167 std::atomic<bool> _stopped;
168
169 std::unique_ptr<std::thread> _thread;
170
172
173 std::mutex _newSocketsLock;
175
179};
180}
181
182#endif // TRINITYCORE_NETWORK_THREAD_H
int32_t int32
Definition Define.h:129
#define ASSERT
Definition Errors.h:68
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
virtual void AddSocket(std::shared_ptr< SocketType > sock)
NetworkThread & operator=(NetworkThread &&)=delete
Trinity::Asio::IoContext _ioContext
NetworkThread(NetworkThread const &)=delete
Trinity::Asio::DeadlineTimer _updateTimer
Trinity::Net::IoContextTcpSocket * GetSocketForAccept()
NetworkThread & operator=(NetworkThread const &)=delete
virtual void SocketAdded(std::shared_ptr< SocketType > const &)
std::atomic< int32 > _connections
std::unique_ptr< std::thread > _thread
std::atomic< bool > _stopped
Trinity::Net::IoContextTcpSocket _acceptSocket
NetworkThread(NetworkThread &&)=delete
std::vector< std::shared_ptr< SocketType > > SocketContainer
virtual void SocketRemoved(std::shared_ptr< SocketType > const &)
void EraseIf(Container &c, Predicate p)
Definition Containers.h:231
boost::asio::basic_stream_socket< boost::asio::ip::tcp, boost::asio::io_context::executor_type > IoContextTcpSocket
Definition Socket.h:41