aboutsummaryrefslogtreecommitdiff
path: root/src/torcontrol.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2016-03-03 13:28:07 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2016-03-03 13:31:26 +0100
commite2195037116f47b11b66452351dba4fe606423a2 (patch)
tree649891536f56b5f2f0909b23a0883d38fbc1ffb2 /src/torcontrol.cpp
parent1b68de35250e7c00105eac5c2533b97f4e97dc27 (diff)
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.
Diffstat (limited to 'src/torcontrol.cpp')
-rw-r--r--src/torcontrol.cpp13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
index 10170dbcea..a04b5c3024 100644
--- a/src/torcontrol.cpp
+++ b/src/torcontrol.cpp
@@ -398,6 +398,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) )) {
@@ -413,8 +416,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);
}
@@ -626,8 +631,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;
}