ni/easyrdma

SessionManager locking

Closed this issue · 3 comments

I am reading easyrdma code, it seems there is a locking period problem:


RdmaSessionRef GetSession(easyrdma_Session session, tAccessType access = kAccess_Exclusive, tCheckDeferredCloseTable checkDeferredCloseTable = tCheckDeferredCloseTable::No)
{
std::unique_lockstd::mutex guard(mapLock);
auto it = sessionMap.find(session);
if (it != sessionMap.end()) {
return RdmaSessionRef(it->second, access);
}


calling RdmaSessionRef(it->second, access) can block, then because mapLock is locked, no other threads can access the SessionManager.

Yes, there are locks at both levels, but both locks are designed to be held only briefly. The lock on the session itself is released when doing any blocking operation (there is a concept of suspending access).

Are you encountering a situation where the lock it not getting released immediately?

I am just confused, because you are safe to copy it->second which is shared_ptr and unlock mapLock before passing it to RdmaSessionRef instead of current implementation

It’s because there is more state involved (the access manager) than just the lifetime of the shared pointer. Note that shared pointers have an inherent synchronization involved in their ref counting as well.

Holding one lock while acquiring another isn’t inherently bad, it just needs to be done with proper ordering to prevent deadlocks (which it should be doing) and limited scope/duration to prevent contention. The access manager is designed so that all blocking operations release exclusive access to the session first, so getting a reference while holding the map lock should also not block either.