From abed887d875ed76ae01457ee1456f43923919b4e Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 2 Apr 2018 12:38:42 -0700 Subject: [PATCH] beaconEmitter: avoid ref. loop with Timer emitter schedules itself and timer holds a ref. while queued. So the emitter isn't destroyed until the timer expires. --- src/server/beaconEmitter.cpp | 12 +++++++++--- src/server/pv/beaconEmitter.h | 7 ++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/server/beaconEmitter.cpp b/src/server/beaconEmitter.cpp index b1b0ea4..9001085 100644 --- a/src/server/beaconEmitter.cpp +++ b/src/server/beaconEmitter.cpp @@ -109,12 +109,16 @@ void BeaconEmitter::timerStopped() void BeaconEmitter::destroy() { - _timer->cancel(shared_from_this()); + Timer::shared_pointer timer(_timer.lock()); + if(timer) + timer->cancel(shared_from_this()); } void BeaconEmitter::start() { - _timer->scheduleAfterDelay(shared_from_this(), 0.0); + Timer::shared_pointer timer(_timer.lock()); + if(timer) + timer->scheduleAfterDelay(shared_from_this(), 0.0); } void BeaconEmitter::reschedule() @@ -122,7 +126,9 @@ void BeaconEmitter::reschedule() const double period = (_beaconSequenceID >= _beaconCountLimit) ? _slowBeaconPeriod : _fastBeaconPeriod; if (period > 0) { - _timer->scheduleAfterDelay(shared_from_this(), period); + Timer::shared_pointer timer(_timer.lock()); + if(timer) + timer->scheduleAfterDelay(shared_from_this(), period); } } diff --git a/src/server/pv/beaconEmitter.h b/src/server/pv/beaconEmitter.h index badcd7a..cdc68d9 100644 --- a/src/server/pv/beaconEmitter.h +++ b/src/server/pv/beaconEmitter.h @@ -142,10 +142,11 @@ private: */ BeaconServerStatusProvider::shared_pointer _serverStatusProvider; - /** - * Timer. + /** Timer is referenced by server context, which also references us. + * We will also be queuing ourselves, and be referenced by Timer. + * So keep only a weak ref to Timer to avoid possible ref. loop. */ - epics::pvData::Timer::shared_pointer _timer; + epics::pvData::Timer::weak_pointer _timer; }; }