Skip to content

Commit c4e4658

Browse files
authored
Merge 4402841 into f1268ad
2 parents f1268ad + 4402841 commit c4e4658

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

src/remote/pv/beaconHandler.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@
2626
#include <pv/remote.h>
2727
#include <pv/pvAccess.h>
2828

29+
namespace
30+
{
31+
class InternalClientContextImpl;
32+
class BeaconCleanupHandler;
33+
}
34+
2935
namespace epics {
3036
namespace pvAccess {
3137

@@ -85,6 +91,10 @@ class BeaconHandler
8591
* First beacon flag.
8692
*/
8793
bool _first;
94+
/**
95+
* Callback for cleaning up the beacon
96+
*/
97+
std::shared_ptr<BeaconCleanupHandler> _callback;
8898

8999
/**
90100
* Update beacon.
@@ -100,6 +110,8 @@ class BeaconHandler
100110
ServerGUID const &guid,
101111
epics::pvData::int16 sequentalID,
102112
epics::pvData::int16 changeCount);
113+
114+
friend class ::InternalClientContextImpl;
103115
};
104116

105117
}

src/remoteClient/clientContextImpl.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ using std::tr1::static_pointer_cast;
4949
using namespace std;
5050
using namespace epics::pvData;
5151

52+
static const float maxBeaconLifetime = 180.f * 2.f;
53+
static const int maxTrackedBeacons = 20000;
54+
5255
namespace epics {
5356
namespace pvAccess {
5457

@@ -3038,7 +3041,43 @@ enum ContextState {
30383041
};
30393042

30403043

3044+
/**
3045+
* Handles cleanup of old beacons.
3046+
*/
3047+
class BeaconCleanupHandler
3048+
{
3049+
public:
3050+
POINTER_DEFINITIONS(BeaconCleanupHandler);
30413051

3052+
class Callback : public TimerCallback
3053+
{
3054+
public:
3055+
Callback(BeaconCleanupHandler& handler) : m_handler(handler)
3056+
{
3057+
}
3058+
3059+
virtual void callback() OVERRIDE FINAL;
3060+
virtual void timerStopped() OVERRIDE FINAL;
3061+
3062+
BeaconCleanupHandler& m_handler;
3063+
};
3064+
3065+
BeaconCleanupHandler(InternalClientContextImpl& impl, osiSockAddr addr);
3066+
~BeaconCleanupHandler();
3067+
3068+
/**
3069+
* Set the last time used to the current time
3070+
*/
3071+
void touch() { epicsTimeGetCurrent(&m_lastTime); }
3072+
3073+
private:
3074+
void remove();
3075+
3076+
std::shared_ptr<Callback> m_callback;
3077+
osiSockAddr m_from;
3078+
InternalClientContextImpl& m_impl;
3079+
epicsTimeStamp m_lastTime;
3080+
};
30423081

30433082
class InternalClientContextImpl :
30443083
public ClientContextImpl,
@@ -4351,12 +4390,25 @@ class InternalClientContextImpl :
43514390
BeaconHandler::shared_pointer handler;
43524391
if (it == m_beaconHandlers.end())
43534392
{
4393+
/* If we're tracking too many beacons, we'll just ignore this one */
4394+
if (m_beaconHandlers.size() >= maxTrackedBeacons)
4395+
{
4396+
char ipa[64];
4397+
sockAddrToDottedIP(&responseFrom->sa, ipa, sizeof(ipa));
4398+
LOG(logLevelWarn, "Tracked beacon limit reached (%d), ignoring %s\n", maxTrackedBeacons, ipa);
4399+
return nullptr;
4400+
}
4401+
43544402
// stores weak_ptr
43554403
handler.reset(new BeaconHandler(internal_from_this(), responseFrom));
4404+
handler->_callback = std::make_shared<BeaconCleanupHandler>(*this, *responseFrom);
43564405
m_beaconHandlers[*responseFrom] = handler;
43574406
}
43584407
else
4408+
{
43594409
handler = it->second;
4410+
handler->_callback->touch(); /* Update the callback's latest use time */
4411+
}
43604412
return handler;
43614413
}
43624414

@@ -4556,8 +4608,44 @@ class InternalClientContextImpl :
45564608
Configuration::shared_pointer m_configuration;
45574609

45584610
TransportRegistry::transportVector_t m_flushTransports;
4611+
4612+
friend class BeaconCleanupHandler;
45594613
};
45604614

4615+
4616+
BeaconCleanupHandler::BeaconCleanupHandler(InternalClientContextImpl& impl, osiSockAddr addr) :
4617+
m_callback(std::make_shared<Callback>(*this)),
4618+
m_from(addr),
4619+
m_impl(impl)
4620+
{
4621+
m_impl.m_timer->schedulePeriodic(m_callback, maxBeaconLifetime, maxBeaconLifetime);
4622+
}
4623+
4624+
BeaconCleanupHandler::~BeaconCleanupHandler()
4625+
{
4626+
m_impl.m_timer->cancel(m_callback);
4627+
}
4628+
4629+
void BeaconCleanupHandler::Callback::callback()
4630+
{
4631+
epicsTimeStamp ts;
4632+
epicsTimeGetCurrent(&ts);
4633+
if (epicsTimeDiffInSeconds(&ts, &m_handler.m_lastTime) > maxBeaconLifetime)
4634+
m_handler.remove();
4635+
}
4636+
4637+
void BeaconCleanupHandler::Callback::timerStopped()
4638+
{
4639+
m_handler.remove();
4640+
}
4641+
4642+
void BeaconCleanupHandler::remove()
4643+
{
4644+
Lock guard(m_impl.m_beaconMapMutex);
4645+
m_impl.m_timer->cancel(m_callback);
4646+
m_impl.m_beaconHandlers.erase(m_from); /* Erase the beacon entirely */
4647+
}
4648+
45614649
size_t InternalClientContextImpl::num_instances;
45624650
size_t InternalClientContextImpl::InternalChannelImpl::num_instances;
45634651
size_t InternalClientContextImpl::InternalChannelImpl::num_active;

0 commit comments

Comments
 (0)