From 66d54085598205de2182c04739cc418e2d15543c Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 3 Mar 2016 13:28:07 +0100 Subject: [PATCH] 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 --- src/torcontrol.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 6da1f5a98..1a57ad89c 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -394,6 +394,9 @@ TorController::TorController(struct event_base* base, const std::string& target) target(target), conn(base), reconnect(true), reconnect_ev(0), 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 if (!conn.Connect(target, boost::bind(&TorController::connected_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() { - if (reconnect_ev) - event_del(reconnect_ev); + if (reconnect_ev) { + event_free(reconnect_ev); + reconnect_ev = 0; + } if (service.IsValid()) { RemoveLocal(service); } @@ -622,8 +627,8 @@ void TorController::disconnected_cb(TorControlConnection& conn) // Single-shot timer for reconnect. Use exponential backoff. struct timeval time = MillisToTimeval(int64_t(reconnect_timeout * 1000.0)); - reconnect_ev = event_new(base, -1, 0, reconnect_cb, this); - event_add(reconnect_ev, &time); + if (reconnect_ev) + event_add(reconnect_ev, &time); reconnect_timeout *= RECONNECT_TIMEOUT_EXP; }