Introduce `ObjectNamesMutex` helper class

This commit is contained in:
Yonas Habteab 2024-02-13 14:51:26 +01:00
parent 008fcd1744
commit 40011b0584
2 changed files with 54 additions and 0 deletions

View File

@ -462,3 +462,37 @@ void ApiListener::SendRuntimeConfigObjects(const JsonRpcConnection::Ptr& aclient
Log(LogInformation, "ApiListener")
<< "Finished syncing runtime objects to endpoint '" << endpoint->GetName() << "'.";
}
/**
* Locks the specified object name of the given type. If it is already locked, the call blocks until the lock is released.
*
* @param Type::Ptr ptype The type of the object you want to lock
* @param String objName The object name you want to lock
*/
void ObjectNameMutex::Lock(const Type::Ptr& ptype, const String& objName)
{
std::unique_lock<std::mutex> lock(m_Mutex);
m_CV.wait(lock, [this, &ptype, &objName]{
auto& locked = m_LockedObjectNames[ptype.get()];
return locked.find(objName) == locked.end();
});
// Add object name to the locked list again to block all other threads that try
// to process a message affecting the same object.
m_LockedObjectNames[ptype.get()].emplace(objName);
}
/**
* Unlocks the specified object name of the given type.
*
* @param Type::Ptr ptype The type of the object you want to unlock
* @param String objName The name of the object you want to unlock
*/
void ObjectNameMutex::Unlock(const Type::Ptr& ptype, const String& objName)
{
{
std::unique_lock<std::mutex> lock(m_Mutex);
m_LockedObjectNames[ptype.get()].erase(objName);
}
m_CV.notify_all();
}

View File

@ -71,6 +71,26 @@ enum class ApiCapabilities : uint_fast64_t
IfwApiCheckCommand = 1u << 1u,
};
/**
* Allows you to easily lock/unlock a specific object of a given type by its name.
*
* That way, locking an object "this" of type Host does not affect an object "this" of
* type "Service" nor an object "other" of type "Host".
*
* @ingroup remote
*/
class ObjectNameMutex
{
public:
void Lock(const Type::Ptr& ptype, const String& objName);
void Unlock(const Type::Ptr& ptype, const String& objName);
private:
std::mutex m_Mutex;
std::condition_variable m_CV;
std::map<Type*, std::set<String>> m_LockedObjectNames;
};
/**
* @ingroup remote
*/