diff --git a/src/common/lookups/AffiliationLookup.cpp b/src/common/lookups/AffiliationLookup.cpp index 168196aa..e4dde41c 100644 --- a/src/common/lookups/AffiliationLookup.cpp +++ b/src/common/lookups/AffiliationLookup.cpp @@ -20,6 +20,12 @@ using namespace lookups; const uint32_t UNIT_REG_TIMEOUT = 43200U; // 12 hours +// --------------------------------------------------------------------------- +// Static Class Members +// --------------------------------------------------------------------------- + +std::mutex AffiliationLookup::m_mutex; + // --------------------------------------------------------------------------- // Public Class Members // --------------------------------------------------------------------------- @@ -297,6 +303,7 @@ bool AffiliationLookup::grantCh(uint32_t dstId, uint32_t srcId, uint32_t grantTi return false; } + std::lock_guard lock(m_mutex); uint32_t chNo = m_chLookup->getFirstRFChannel(); m_chLookup->removeRFCh(chNo); @@ -326,6 +333,7 @@ void AffiliationLookup::touchGrant(uint32_t dstId) return; } + std::lock_guard lock(m_mutex); if (isGranted(dstId)) { m_grantTimers[dstId].start(); } @@ -333,12 +341,15 @@ void AffiliationLookup::touchGrant(uint32_t dstId) /* Helper to release the channel grant for the destination ID. */ -bool AffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll) +bool AffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll, bool noLock) { if (dstId == 0U && !releaseAll) { return false; } + if (!noLock) + m_mutex.lock(); + // are we trying to release all grants? if (dstId == 0U && releaseAll) { LogWarning(LOG_HOST, "%s, force releasing all channel grants", m_name.c_str()); @@ -354,6 +365,8 @@ bool AffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll) releaseGrant(dstId, false); } + if (!noLock) + m_mutex.unlock(); return true; } @@ -383,9 +396,14 @@ bool AffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll) } m_grantTimers[dstId].stop(); + + if (!noLock) + m_mutex.unlock(); return true; } + if (!noLock) + m_mutex.unlock(); return false; } @@ -527,6 +545,8 @@ uint32_t AffiliationLookup::getGrantedSrcId(uint32_t dstId) void AffiliationLookup::clock(uint32_t ms) { + std::lock_guard lock(m_mutex); + // clock all the grant timers std::vector gntsToRel = std::vector(); for (auto entry : m_grantChTable) { @@ -540,7 +560,7 @@ void AffiliationLookup::clock(uint32_t ms) // release grants that have timed out for (uint32_t dstId : gntsToRel) { - releaseGrant(dstId, false); + releaseGrant(dstId, false, true); } if (!m_disableUnitRegTimeout) { diff --git a/src/common/lookups/AffiliationLookup.h b/src/common/lookups/AffiliationLookup.h index 1edc4a39..2c7ac586 100644 --- a/src/common/lookups/AffiliationLookup.h +++ b/src/common/lookups/AffiliationLookup.h @@ -29,6 +29,7 @@ #include #include #include +#include namespace lookups { @@ -182,9 +183,10 @@ namespace lookups * @brief Helper to release the channel grant for the destination ID. * @param dstId Destination Address. * @param releaseAll Flag indicating all channel grants should be released. + * @param noLock Flag indicating no mutex lock operation should be performed while releasing. * @returns bool True, if channel grant was released, otherwise false. */ - virtual bool releaseGrant(uint32_t dstId, bool releaseAll); + virtual bool releaseGrant(uint32_t dstId, bool releaseAll, bool noLock = false); /** * @brief Helper to determine if the channel number is busy. * @param chNo Channel Number. @@ -298,6 +300,8 @@ namespace lookups bool m_disableUnitRegTimeout; bool m_verbose; + + static std::mutex m_mutex; }; } // namespace lookups diff --git a/src/host/dmr/lookups/DMRAffiliationLookup.cpp b/src/host/dmr/lookups/DMRAffiliationLookup.cpp index 9791fa61..37b1c540 100644 --- a/src/host/dmr/lookups/DMRAffiliationLookup.cpp +++ b/src/host/dmr/lookups/DMRAffiliationLookup.cpp @@ -86,12 +86,15 @@ bool DMRAffiliationLookup::grantChSlot(uint32_t dstId, uint32_t srcId, uint8_t s /* Helper to release the channel grant for the destination ID. */ -bool DMRAffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll) +bool DMRAffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll, bool noLock) { if (dstId == 0U && !releaseAll) { return false; } + if (!noLock) + m_mutex.lock(); + // are we trying to release all grants? if (dstId == 0U && releaseAll) { LogWarning(LOG_HOST, "%s, force releasing all channel grants", m_name.c_str()); @@ -107,6 +110,8 @@ bool DMRAffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll) releaseGrant(dstId, false); } + if (!noLock) + m_mutex.unlock(); return true; } @@ -139,9 +144,14 @@ bool DMRAffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll) } m_grantTimers[dstId].stop(); + + if (!noLock) + m_mutex.unlock(); return true; } + if (!noLock) + m_mutex.unlock(); return false; } diff --git a/src/host/dmr/lookups/DMRAffiliationLookup.h b/src/host/dmr/lookups/DMRAffiliationLookup.h index 90c85125..0e394f12 100644 --- a/src/host/dmr/lookups/DMRAffiliationLookup.h +++ b/src/host/dmr/lookups/DMRAffiliationLookup.h @@ -76,9 +76,10 @@ namespace dmr * @brief Helper to release the channel grant for the destination ID. * @param dstId Destination Address. * @param releaseAll Flag indicating all channel grants should be released. + * @param noLock Flag indicating no mutex lock operation should be performed while releasing. * @returns bool True, if channel grant was released, otherwise false. */ - bool releaseGrant(uint32_t dstId, bool releaseAll) override; + bool releaseGrant(uint32_t dstId, bool releaseAll, bool noLock = false) override; /** * @brief Helper to determine if the channel number is busy. * @param chNo Channel Number. diff --git a/src/host/p25/lookups/P25AffiliationLookup.cpp b/src/host/p25/lookups/P25AffiliationLookup.cpp index 72dda5e5..10bdbedf 100644 --- a/src/host/p25/lookups/P25AffiliationLookup.cpp +++ b/src/host/p25/lookups/P25AffiliationLookup.cpp @@ -46,9 +46,9 @@ std::vector P25AffiliationLookup::clearGroupAff(uint32_t dstId, bool r /* Helper to release the channel grant for the destination ID. */ -bool P25AffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll) +bool P25AffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll, bool noLock) { - bool ret = ::lookups::AffiliationLookup::releaseGrant(dstId, releaseAll); + bool ret = ::lookups::AffiliationLookup::releaseGrant(dstId, releaseAll, noLock); if (ret) { if (m_rfGrantChCnt > 0U) { m_p25->m_siteData.setChCnt(m_chLookup->rfChSize() + m_rfGrantChCnt); diff --git a/src/host/p25/lookups/P25AffiliationLookup.h b/src/host/p25/lookups/P25AffiliationLookup.h index 56540b6a..875f524f 100644 --- a/src/host/p25/lookups/P25AffiliationLookup.h +++ b/src/host/p25/lookups/P25AffiliationLookup.h @@ -72,9 +72,10 @@ namespace p25 * @brief Helper to release the channel grant for the destination ID. * @param dstId Destination Address. * @param releaseAll Flag indicating all channel grants should be released. + * @param noLock Flag indicating no mutex lock operation should be performed while releasing. * @returns bool True, if channel grant was released, otherwise false. */ - bool releaseGrant(uint32_t dstId, bool releaseAll) override; + bool releaseGrant(uint32_t dstId, bool releaseAll, bool noLock = false) override; /** @} */ protected: