Fix cUrlClient leak (#4125)

Fixes #4040
* The TCP connection is now shutdown after OnBodyFinished
* Any open connections are closed when cNetworkSingleton::Terminate() is called.
* Removed ownership cycles in cUrlClientRequest
* Added a check to the test to ensure there are no leaks.
This commit is contained in:
peterbell10
2018-02-20 17:08:46 +00:00
committed by GitHub
parent cf75d7b2c5
commit 1ea36298d2
4 changed files with 73 additions and 41 deletions
+22 -7
View File
@@ -6,6 +6,7 @@
#include "Globals.h"
#include "NetworkSingleton.h"
#include "OSSupport/Network.h"
#include <event2/thread.h>
#include <event2/bufferevent.h>
#include <event2/listener.h>
@@ -102,11 +103,25 @@ void cNetworkSingleton::Terminate(void)
event_base_loopbreak(m_EventBase);
m_EventLoopThread.join();
// Remove all objects:
// Close all open connections:
{
cCSLock Lock(m_CS);
m_Connections.clear();
m_Servers.clear();
// Must take copies because Close will modify lists
auto Conns = m_Connections;
for (auto & Conn : Conns)
{
Conn->Close();
}
auto Servers = m_Servers;
for (auto & Server : Servers)
{
Server->Close();
}
// Closed handles should have removed themself
ASSERT(m_Connections.empty());
ASSERT(m_Servers.empty());
}
// Free the underlying LibEvent objects:
@@ -167,7 +182,7 @@ void cNetworkSingleton::SignalizeStartup(evutil_socket_t a_Socket, short a_Event
void cNetworkSingleton::AddLink(cTCPLinkImplPtr a_Link)
void cNetworkSingleton::AddLink(cTCPLinkPtr a_Link)
{
ASSERT(!m_HasTerminated);
cCSLock Lock(m_CS);
@@ -178,7 +193,7 @@ void cNetworkSingleton::AddLink(cTCPLinkImplPtr a_Link)
void cNetworkSingleton::RemoveLink(const cTCPLinkImpl * a_Link)
void cNetworkSingleton::RemoveLink(const cTCPLink * a_Link)
{
ASSERT(!m_HasTerminated);
cCSLock Lock(m_CS);
@@ -196,7 +211,7 @@ void cNetworkSingleton::RemoveLink(const cTCPLinkImpl * a_Link)
void cNetworkSingleton::AddServer(cServerHandleImplPtr a_Server)
void cNetworkSingleton::AddServer(cServerHandlePtr a_Server)
{
ASSERT(!m_HasTerminated);
cCSLock Lock(m_CS);
@@ -207,7 +222,7 @@ void cNetworkSingleton::AddServer(cServerHandleImplPtr a_Server)
void cNetworkSingleton::RemoveServer(const cServerHandleImpl * a_Server)
void cNetworkSingleton::RemoveServer(const cServerHandle * a_Server)
{
ASSERT(!m_HasTerminated);
cCSLock Lock(m_CS);
+12 -12
View File
@@ -24,12 +24,12 @@
// fwd:
struct event_base;
class cTCPLinkImpl;
typedef std::shared_ptr<cTCPLinkImpl> cTCPLinkImplPtr;
typedef std::vector<cTCPLinkImplPtr> cTCPLinkImplPtrs;
class cServerHandleImpl;
typedef std::shared_ptr<cServerHandleImpl> cServerHandleImplPtr;
typedef std::vector<cServerHandleImplPtr> cServerHandleImplPtrs;
class cTCPLink;
typedef std::shared_ptr<cTCPLink> cTCPLinkPtr;
typedef std::vector<cTCPLinkPtr> cTCPLinkPtrs;
class cServerHandle;
typedef std::shared_ptr<cServerHandle> cServerHandlePtr;
typedef std::vector<cServerHandlePtr> cServerHandlePtrs;
@@ -61,20 +61,20 @@ public:
/** Adds the specified link to m_Connections.
Used by the underlying link implementation when a new link is created. */
void AddLink(cTCPLinkImplPtr a_Link);
void AddLink(cTCPLinkPtr a_Link);
/** Removes the specified link from m_Connections.
Used by the underlying link implementation when the link is closed / errored. */
void RemoveLink(const cTCPLinkImpl * a_Link);
void RemoveLink(const cTCPLink * a_Link);
/** Adds the specified link to m_Servers.
Used by the underlying server handle implementation when a new listening server is created.
Only servers that succeed in listening are added. */
void AddServer(cServerHandleImplPtr a_Server);
void AddServer(cServerHandlePtr a_Server);
/** Removes the specified server from m_Servers.
Used by the underlying server handle implementation when the server is closed. */
void RemoveServer(const cServerHandleImpl * a_Server);
void RemoveServer(const cServerHandle * a_Server);
protected:
@@ -82,10 +82,10 @@ protected:
event_base * m_EventBase;
/** Container for all client connections, including ones with pending-connect. */
cTCPLinkImplPtrs m_Connections;
cTCPLinkPtrs m_Connections;
/** Container for all servers that are currently active. */
cServerHandleImplPtrs m_Servers;
cServerHandlePtrs m_Servers;
/** Mutex protecting all containers against multithreaded access. */
cCriticalSection m_CS;