diff options
author | Mattes D <github@xoft.cz> | 2015-01-12 15:45:30 +0100 |
---|---|---|
committer | Mattes D <github@xoft.cz> | 2015-01-22 20:12:50 +0100 |
commit | ddb1818dd54d82e19e7f629e6a729bccb68bfcf1 (patch) | |
tree | 1508749651cc4291a92156301772ff6c5552b38a /src/OSSupport/Network.cpp | |
parent | cNetwork: Implemented connection shutdown and close. (diff) | |
download | cuberite-ddb1818dd54d82e19e7f629e6a729bccb68bfcf1.tar cuberite-ddb1818dd54d82e19e7f629e6a729bccb68bfcf1.tar.gz cuberite-ddb1818dd54d82e19e7f629e6a729bccb68bfcf1.tar.bz2 cuberite-ddb1818dd54d82e19e7f629e6a729bccb68bfcf1.tar.lz cuberite-ddb1818dd54d82e19e7f629e6a729bccb68bfcf1.tar.xz cuberite-ddb1818dd54d82e19e7f629e6a729bccb68bfcf1.tar.zst cuberite-ddb1818dd54d82e19e7f629e6a729bccb68bfcf1.zip |
Diffstat (limited to 'src/OSSupport/Network.cpp')
-rw-r--r-- | src/OSSupport/Network.cpp | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/src/OSSupport/Network.cpp b/src/OSSupport/Network.cpp index 2ef6ace3c..bee5bc09f 100644 --- a/src/OSSupport/Network.cpp +++ b/src/OSSupport/Network.cpp @@ -12,6 +12,7 @@ #include <event2/listener.h> #include <thread> #include "Event.h" +#include "CriticalSection.h" @@ -197,6 +198,9 @@ protected: /** Container for all currently active connections on this server. */ cTCPLinkImplPtrs m_Connections; + /** Mutex protecting m_Connections againt multithreaded access. */ + cCriticalSection m_CS; + /** The callback called by LibEvent upon incoming connection. */ static void Callback(evconnlistener * a_Listener, evutil_socket_t a_Socket, sockaddr * a_Addr, int a_Len, void * a_Self); @@ -289,6 +293,9 @@ protected: /** Container for all pending IP lookups. */ cIPLookupPtrs m_IPLookups; + /** Mutex protecting all containers against multithreaded access. */ + cCriticalSection m_CS; + /** Initializes the LibEvent internals. */ cNetworkSingleton(void); @@ -587,6 +594,7 @@ void cTCPLinkImpl::Shutdown(void) void cTCPLinkImpl::Close(void) { + // Disable all events on the socket, but keep it alive (multithreading): bufferevent_disable(m_BufferEvent, EV_READ | EV_WRITE); if (m_Server == nullptr) { @@ -790,7 +798,10 @@ void cServerHandleImpl::Close(void) // Shutdown all connections: cTCPLinkImplPtrs Conns; - std::swap(Conns, m_Connections); + { + cCSLock Lock(m_CS); + std::swap(Conns, m_Connections); + } for (auto conn: Conns) { conn->Shutdown(); @@ -902,7 +913,10 @@ void cServerHandleImpl::Callback(evconnlistener * a_Listener, evutil_socket_t a_ // Create a new cTCPLink for the incoming connection: cTCPLinkImplPtr Link = std::make_shared<cTCPLinkImpl>(a_Socket, Self->m_LinkCallbacks, Self, a_Addr, a_Len); - Self->m_Connections.push_back(Link); + { + cCSLock Lock(Self->m_CS); + Self->m_Connections.push_back(Link); + } // Lock(m_CS) // Call the OnAccepted callback: Self->m_ListenCallbacks->OnAccepted(*Link); @@ -914,6 +928,7 @@ void cServerHandleImpl::Callback(evconnlistener * a_Listener, evutil_socket_t a_ void cServerHandleImpl::RemoveLink(const cTCPLinkImpl * a_Link) { + cCSLock Lock(m_CS); for (auto itr = m_Connections.begin(), end = m_Connections.end(); itr != end; ++itr) { if (itr->get() == a_Link) @@ -1060,7 +1075,10 @@ bool cNetworkSingleton::Connect( { // Add a connection request to the queue: cTCPLinkImplPtr ConnRequest = std::make_shared<cTCPLinkImpl>(a_LinkCallbacks); - m_Connections.push_back(ConnRequest); + { + cCSLock Lock(m_CS); + m_Connections.push_back(ConnRequest); + } // Lock(m_CS) // Queue the connection: if (!ConnRequest->Connect(a_Host, a_Port, a_ConnectCallbacks)) @@ -1088,6 +1106,7 @@ cServerHandlePtr cNetworkSingleton::Listen( { return res; } + cCSLock Lock(m_CS); m_Servers.push_back(res); return res; } @@ -1103,6 +1122,7 @@ bool cNetworkSingleton::HostnameToIP( { try { + cCSLock Lock(m_CS); m_HostnameLookups.push_back(std::make_shared<cHostnameLookup>(a_Hostname, a_Callbacks)); } catch (...) @@ -1122,6 +1142,7 @@ bool cNetworkSingleton::IPToHostName( { try { + cCSLock Lock(m_CS); m_IPLookups.push_back(std::make_shared<cIPLookup>(a_IP, a_Callbacks)); } catch (...) @@ -1165,6 +1186,7 @@ void cNetworkSingleton::RunEventLoop(cNetworkSingleton * a_Self) void cNetworkSingleton::RemoveHostnameLookup(const cHostnameLookup * a_HostnameLookup) { + cCSLock Lock(m_CS); for (auto itr = m_HostnameLookups.begin(), end = m_HostnameLookups.end(); itr != end; ++itr) { if (itr->get() == a_HostnameLookup) @@ -1181,6 +1203,7 @@ void cNetworkSingleton::RemoveHostnameLookup(const cHostnameLookup * a_HostnameL void cNetworkSingleton::RemoveIPLookup(const cIPLookup * a_IPLookup) { + cCSLock Lock(m_CS); for (auto itr = m_IPLookups.begin(), end = m_IPLookups.end(); itr != end; ++itr) { if (itr->get() == a_IPLookup) @@ -1197,6 +1220,7 @@ void cNetworkSingleton::RemoveIPLookup(const cIPLookup * a_IPLookup) void cNetworkSingleton::RemoveLink(const cTCPLinkImpl * a_Link) { + cCSLock Lock(m_CS); for (auto itr = m_Connections.begin(), end = m_Connections.end(); itr != end; ++itr) { if (itr->get() == a_Link) |