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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user