TrinityCore
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 NetworkThread_h__
19#define NetworkThread_h__
20
21#include "Define.h"
22#include "DeadlineTimer.h"
23#include "Errors.h"
24#include "IoContext.h"
25#include "Log.h"
26#include <boost/asio/ip/tcp.hpp>
27#include <atomic>
28#include <memory>
29#include <mutex>
30#include <thread>
31
32template<class SocketType>
34{
35public:
38 {
39 }
40
42 {
43 Stop();
44 if (_thread)
45 {
46 Wait();
47 delete _thread;
48 }
49 }
50
51 void Stop()
52 {
53 _stopped = true;
55 }
56
57 bool Start()
58 {
59 if (_thread)
60 return false;
61
62 _thread = new std::thread(&NetworkThread::Run, this);
63 return true;
64 }
65
66 void Wait()
67 {
69
70 _thread->join();
71 delete _thread;
72 _thread = nullptr;
73 }
74
76 {
77 return _connections;
78 }
79
80 void AddSocket(std::shared_ptr<SocketType> sock)
81 {
82 std::lock_guard<std::mutex> lock(_newSocketsLock);
83
85 _newSockets.push_back(sock);
86 SocketAdded(sock);
87 }
88
89 boost::asio::ip::tcp::socket* GetSocketForAccept() { return &_acceptSocket; }
90
91protected:
92 virtual void SocketAdded(std::shared_ptr<SocketType> /*sock*/) { }
93 virtual void SocketRemoved(std::shared_ptr<SocketType> /*sock*/) { }
94
96 {
97 std::lock_guard<std::mutex> lock(_newSocketsLock);
98
99 if (_newSockets.empty())
100 return;
101
102 for (std::shared_ptr<SocketType> sock : _newSockets)
103 {
104 if (!sock->IsOpen())
105 {
106 SocketRemoved(sock);
107 --_connections;
108 }
109 else
110 _sockets.push_back(sock);
111 }
112
113 _newSockets.clear();
114 }
115
116 void Run()
117 {
118 TC_LOG_DEBUG("misc", "Network Thread Starting");
119
120 _updateTimer.expires_from_now(boost::posix_time::milliseconds(1));
121 _updateTimer.async_wait([this](boost::system::error_code const&) { Update(); });
122 _ioContext.run();
123
124 TC_LOG_DEBUG("misc", "Network Thread exits");
125 _newSockets.clear();
126 _sockets.clear();
127 }
128
129 void Update()
130 {
131 if (_stopped)
132 return;
133
134 _updateTimer.expires_from_now(boost::posix_time::milliseconds(1));
135 _updateTimer.async_wait([this](boost::system::error_code const&) { Update(); });
136
138
139 _sockets.erase(std::remove_if(_sockets.begin(), _sockets.end(), [this](std::shared_ptr<SocketType> sock)
140 {
141 if (!sock->Update())
142 {
143 if (sock->IsOpen())
144 sock->CloseSocket();
145
146 this->SocketRemoved(sock);
147
148 --this->_connections;
149 return true;
150 }
151
152 return false;
153 }), _sockets.end());
154 }
155
156private:
157 typedef std::vector<std::shared_ptr<SocketType>> SocketContainer;
158
159 std::atomic<int32> _connections;
160 std::atomic<bool> _stopped;
161
162 std::thread* _thread;
163
165
166 std::mutex _newSocketsLock;
168
170 boost::asio::ip::tcp::socket _acceptSocket;
172};
173
174#endif // NetworkThread_h__
int32_t int32
Definition: Define.h:138
#define ASSERT
Definition: Errors.h:68
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
virtual void SocketRemoved(std::shared_ptr< SocketType >)
Definition: NetworkThread.h:93
int32 GetConnectionCount() const
Definition: NetworkThread.h:75
std::thread * _thread
SocketContainer _sockets
boost::asio::ip::tcp::socket _acceptSocket
virtual void SocketAdded(std::shared_ptr< SocketType >)
Definition: NetworkThread.h:92
std::mutex _newSocketsLock
boost::asio::ip::tcp::socket * GetSocketForAccept()
Definition: NetworkThread.h:89
Trinity::Asio::DeadlineTimer _updateTimer
Trinity::Asio::IoContext _ioContext
void AddNewSockets()
Definition: NetworkThread.h:95
std::vector< std::shared_ptr< SocketType > > SocketContainer
std::atomic< bool > _stopped
SocketContainer _newSockets
virtual ~NetworkThread()
Definition: NetworkThread.h:41
void AddSocket(std::shared_ptr< SocketType > sock)
Definition: NetworkThread.h:80
std::atomic< int32 > _connections
std::size_t run()
Definition: IoContext.h:40