@@ -3957,7 +3957,7 @@ class InternalClientContextImpl :
39573957 static size_t num_instances;
39583958
39593959 InternalClientContextImpl (const Configuration::shared_pointer& conf) :
3960- m_addressList (" " ), m_autoAddressList(true ), m_connectionTimeout(30 .0f ), m_beaconPeriod(15 .0f ),
3960+ m_addressList (" " ), m_autoAddressList(true ), m_connectionTimeout(30 .0f ), m_beaconPeriod(15 .0f ), m_maxBeacons( 10 ), m_maxBeaconLifetime( 15 ),
39613961 m_broadcastPort (PVA_BROADCAST_PORT), m_receiveBufferSize(MAX_TCP_RECV),
39623962 m_lastCID (0x10203040 ),
39633963 m_lastIOID (0x80706050 ),
@@ -4021,6 +4021,8 @@ class InternalClientContextImpl :
40214021 out << " AUTO_ADDR_LIST : " << (m_autoAddressList ? " true" : " false" ) << std::endl;
40224022 out << " CONNECTION_TIMEOUT : " << m_connectionTimeout << std::endl;
40234023 out << " BEACON_PERIOD : " << m_beaconPeriod << std::endl;
4024+ out << " BEACON_MAX : " << m_maxBeacons << std::endl;
4025+ out << " BEACON_MAX_AGE : " << m_maxBeaconLifetime << std::endl;
40244026 out << " BROADCAST_PORT : " << m_broadcastPort << std::endl;;
40254027 out << " RCV_BUFFER_SIZE : " << m_receiveBufferSize << std::endl;
40264028 out << " STATE : " ;
@@ -4115,6 +4117,8 @@ class InternalClientContextImpl :
41154117 m_beaconPeriod = m_configuration->getPropertyAsFloat (" EPICS_PVA_BEACON_PERIOD" , m_beaconPeriod);
41164118 m_broadcastPort = m_configuration->getPropertyAsInteger (" EPICS_PVA_BROADCAST_PORT" , m_broadcastPort);
41174119 m_receiveBufferSize = m_configuration->getPropertyAsInteger (" EPICS_PVA_MAX_ARRAY_BYTES" , m_receiveBufferSize);
4120+ m_maxBeacons = m_configuration->getPropertyAsInteger (" EPICS_PVA_BEACON_MAX" , m_maxBeacons);
4121+ m_maxBeaconLifetime = m_configuration->getPropertyAsFloat (" EPICS_PVA_BEACON_LIFETIME" , m_maxBeaconLifetime);
41184122 }
41194123
41204124 void internalInitialize () {
@@ -4351,6 +4355,38 @@ class InternalClientContextImpl :
43514355 BeaconHandler::shared_pointer handler;
43524356 if (it == m_beaconHandlers.end ())
43534357 {
4358+ TimeStamp now;
4359+ now.getCurrent ();
4360+
4361+ double oldestAge = -1 ;
4362+ AddressBeaconHandlerMap::iterator oldestBeacon = m_beaconHandlers.end ();
4363+
4364+ /* Before creating a new beacon, cleanup any old ones */
4365+ for (AddressBeaconHandlerMap::iterator it = m_beaconHandlers.begin (); it != m_beaconHandlers.end ();)
4366+ {
4367+ double age = TimeStamp::diff (now, it->second ->getCreationTime ());
4368+ if (age >= m_maxBeaconLifetime)
4369+ {
4370+ AddressBeaconHandlerMap::iterator toErase = it;
4371+ ++it; /* Iterator to current is invalidated by erase, so do this before */
4372+ m_beaconHandlers.erase (toErase);
4373+ continue ;
4374+ }
4375+
4376+ if (age > oldestAge)
4377+ {
4378+ oldestAge = age;
4379+ oldestBeacon = it;
4380+ }
4381+ ++it;
4382+ }
4383+
4384+ /* None were removed, axe the oldest we found to make room */
4385+ if (m_beaconHandlers.size () >= m_maxBeacons && oldestBeacon != m_beaconHandlers.end ())
4386+ {
4387+ m_beaconHandlers.erase (oldestBeacon);
4388+ }
4389+
43544390 // stores weak_ptr
43554391 handler.reset (new BeaconHandler (internal_from_this (), responseFrom));
43564392 m_beaconHandlers[*responseFrom] = handler;
@@ -4443,6 +4479,16 @@ class InternalClientContextImpl :
44434479 */
44444480 float m_beaconPeriod;
44454481
4482+ /* *
4483+ * Max beacons allowed.
4484+ */
4485+ uint32_t m_maxBeacons;
4486+
4487+ /* *
4488+ * Max beacon lifetime
4489+ */
4490+ float m_maxBeaconLifetime;
4491+
44464492 /* *
44474493 * Broadcast (beacon, search) port number to listen to.
44484494 */
0 commit comments