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.
This commit is contained in:
Michael Davidsaver
2018-04-02 12:38:42 -07:00
parent d6a29a2a86
commit abed887d87
2 changed files with 13 additions and 6 deletions

View File

@@ -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);
}
}

View File

@@ -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;
};
}