Fix memleak in TorController [rework]

It looks like, TorController::disconnected_cb(TorControlConnection&
conn) gets called multiple times which results in multiple event_new().

Avoid this by creating the event only once in the constructore, and
deleting it only once in the destructor (thanks to Cory Fields for the
idea).

Replaces the fix by Jonas Schnelli in #7610, see discussion there.

Github-Pull: #7637
Rebased-From: e2195037116f47b11b66452351dba4fe606423a2
This commit is contained in:
Wladimir J. van der Laan 2016-03-03 13:28:07 +01:00 committed by MarcoFalke
parent 1c3d38bde7
commit 66d5408559

View File

@ -394,6 +394,9 @@ TorController::TorController(struct event_base* base, const std::string& target)
target(target), conn(base), reconnect(true), reconnect_ev(0), target(target), conn(base), reconnect(true), reconnect_ev(0),
reconnect_timeout(RECONNECT_TIMEOUT_START) reconnect_timeout(RECONNECT_TIMEOUT_START)
{ {
reconnect_ev = event_new(base, -1, 0, reconnect_cb, this);
if (!reconnect_ev)
LogPrintf("tor: Failed to create event for reconnection: out of memory?\n");
// Start connection attempts immediately // Start connection attempts immediately
if (!conn.Connect(target, boost::bind(&TorController::connected_cb, this, _1), if (!conn.Connect(target, boost::bind(&TorController::connected_cb, this, _1),
boost::bind(&TorController::disconnected_cb, this, _1) )) { boost::bind(&TorController::disconnected_cb, this, _1) )) {
@ -409,8 +412,10 @@ TorController::TorController(struct event_base* base, const std::string& target)
TorController::~TorController() TorController::~TorController()
{ {
if (reconnect_ev) if (reconnect_ev) {
event_del(reconnect_ev); event_free(reconnect_ev);
reconnect_ev = 0;
}
if (service.IsValid()) { if (service.IsValid()) {
RemoveLocal(service); RemoveLocal(service);
} }
@ -622,8 +627,8 @@ void TorController::disconnected_cb(TorControlConnection& conn)
// Single-shot timer for reconnect. Use exponential backoff. // Single-shot timer for reconnect. Use exponential backoff.
struct timeval time = MillisToTimeval(int64_t(reconnect_timeout * 1000.0)); struct timeval time = MillisToTimeval(int64_t(reconnect_timeout * 1000.0));
reconnect_ev = event_new(base, -1, 0, reconnect_cb, this); if (reconnect_ev)
event_add(reconnect_ev, &time); event_add(reconnect_ev, &time);
reconnect_timeout *= RECONNECT_TIMEOUT_EXP; reconnect_timeout *= RECONNECT_TIMEOUT_EXP;
} }