TCallbackContext::LockShared method creates a new TBorrowed object. Its constructor acquires a shared_lock on a mutex stored in the TCallbackContext object.
In a rare situation the LockShared method is called twice in a row from the same thread, but calling lock_shared more than once without releasing the lock leads to undefined behaviour (see https://en.cppreference.com/w/cpp/thread/shared_mutex/lock_shared).
In general, recursive mutexes are frowned upon, but in our case it looks to be the most elegant solution to the problem at hand.
TCallbackContext::LockShared method creates a new TBorrowed object. Its constructor acquires a shared_lock on the mutex stored in the TCallbackContext object.
In a rare situation the LockShared method is called twice in a row from the same thread, but calling lock_shared more than once without releasing the lock leads to undefined behaviour (see https://en.cppreference.com/w/cpp/thread/shared_mutex/lock_shared).
In general, recursive mutexes are frowned upon, but in our case it looks to be the most elegant solution to the problem at hand.