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 <atomic>
28#include <memory>
29#include <mutex>
30#include <thread>
31
32namespace Trinity::Net
33{
34template<class SocketType, class DerivedThread>
36{
37public:
40 {
41 }
42
43 NetworkThread(NetworkThread const&) = delete;
47
49 {
50 Stop();
51 if (_thread)
52 Wait();
53 }
54
55 void Stop()
56 {
57 _stopped = true;
59 }
60
61 bool Start()
62 {
63 if (_thread)
64 return false;
65
66 _thread = std::make_unique<std::thread>(&NetworkThread::Run, this);
67 return true;
68 }
69
70 void Wait()
71 {
73
74 _thread->join();
75 _thread = nullptr;
76 }
77
79 {
80 return _connections;
81 }
82
83 void AddSocket(std::shared_ptr<SocketType>&& sock)
84 {
85 std::scoped_lock lock(_newSocketsLock);
86
88 static_cast<DerivedThread*>(this)->SocketAdded(_newSockets.emplace_back(std::move(sock)));
89 }
90
92
93protected:
94 virtual void SocketAdded(std::shared_ptr<SocketType> const& /*sock*/) { }
95 virtual void SocketRemoved(std::shared_ptr<SocketType> const& /*sock*/) { }
96
98 {
99 std::scoped_lock lock(_newSocketsLock);
100
101 if (_newSockets.empty())
102 return;
103
104 for (std::shared_ptr<SocketType>& sock : _newSockets)
105 {
106 if (!sock->IsOpen())
107 {
108 static_cast<DerivedThread*>(this)->SocketRemoved(sock);
109 --_connections;
110 }
111 else
112 _sockets.emplace_back(std::move(sock));
113 }
114
115 _newSockets.clear();
116 }
117
118 void Run()
119 {
120 TC_LOG_DEBUG("misc", "Network Thread Starting");
121
122 _updateTimer.expires_after(1ms);
123 _updateTimer.async_wait([this](boost::system::error_code const&) { Update(); });
124 _ioContext.run();
125
126 TC_LOG_DEBUG("misc", "Network Thread exits");
127 _newSockets.clear();
128 _sockets.clear();
129 }
130
131 void Update()
132 {
133 if (_stopped)
134 return;
135
136 _updateTimer.expires_after(1ms);
137 _updateTimer.async_wait([this](boost::system::error_code const&) { Update(); });
138
140
141 Trinity::Containers::EraseIf(_sockets, [this](std::shared_ptr<SocketType> const& sock)
142 {
143 if (!sock->Update())
144 {
145 if (sock->IsOpen())
146 sock->CloseSocket();
147
148 static_cast<DerivedThread*>(this)->SocketRemoved(sock);
149
150 --this->_connections;
151 return true;
152 }
153
154 return false;
155 });
156 }
157
158private:
159 typedef std::vector<std::shared_ptr<SocketType>> SocketContainer;
160
161 std::atomic<int32> _connections;
162 std::atomic<bool> _stopped;
163
164 std::unique_ptr<std::thread> _thread;
165
167
168 std::mutex _newSocketsLock;
170
173};
174}
175
176#endif // TRINITYCORE_NETWORK_THREAD_H
int32_t int32
Definition Define.h:150
#define ASSERT
Definition Errors.h:80
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:181
Trinity::Asio::IoContext * GetIoContext()
NetworkThread(NetworkThread const &)=delete
NetworkThread & operator=(NetworkThread &&)=delete
NetworkThread(NetworkThread &&)=delete
virtual void SocketRemoved(std::shared_ptr< SocketType > const &)
Trinity::Asio::DeadlineTimer _updateTimer
std::atomic< bool > _stopped
std::vector< std::shared_ptr< SocketType > > SocketContainer
NetworkThread & operator=(NetworkThread const &)=delete
void AddSocket(std::shared_ptr< SocketType > &&sock)
std::atomic< int32 > _connections
std::unique_ptr< std::thread > _thread
virtual void SocketAdded(std::shared_ptr< SocketType > const &)
Trinity::Asio::IoContext _ioContext
constexpr void EraseIf(Container &c, Predicate p)
Definition Containers.h:283