0

I have data coupled with a Lock = boost::shared_mutex. I am locking data access with

reader locks ReadLock = boost::shared_lock<Lock>

and writer locks WriteLock = boost::unique_lock<Lock>.

Obviously, lots of readers may be reading the data at a time, and only one writing at it. But here's the catch:

A single thread may have mutliple readlocks on the same mutex, because it's calling functions that are locking the data themselves (with a ReadLock). But, as I have found, this causes inter-locking:

  • Thread 1 read-locks data (Lock1)
  • Thread 2 waits with a write-lock (LockW)
  • Thread 1 spawns another read-lock (Lock2) while Lock1 is still alive

Now I get a lock because Lock2 is waiting for LockW to exit, LockW is waiting for Lock1, andLock1 is stuck because of Lock2.

I don't know if it's possible to change the design so that each thread only does a single ReadLock. I believe that having a system that starves Writers would solve my issues. Is there a common way on how to handle my case?

Bill Kotsias
  • 3,258
  • 6
  • 33
  • 60
  • i find it confusing that you talk in terms of locks. If they all lock the same mutex, then what is the problem? – 463035818_is_not_an_ai Apr 11 '18 at 14:02
  • @user463035818 You are right... I am calling the mutex a `Lock` because that's how it's named in the framework I am working on :-) But I have explained what's causing the lock-up in the bullet-list. – Bill Kotsias Apr 11 '18 at 14:04
  • 1
    The common way is always lock mutexes in the same order... always. – UKMonkey Apr 11 '18 at 14:06
  • 1
    Related? https://stackoverflow.com/questions/7125250/making-pthread-rwlock-wrlock-recursive – Roger Lipscombe Apr 11 '18 at 14:10
  • This is a standard deadlock scenario. A ReaderWriterLock is one of the basic synchronization primitives, google can help you find one. Also ensures that multiple threads can read concurrently, you don't have that right now. – Hans Passant Apr 11 '18 at 14:11
  • Why do you think that "Lock2" is going to wait? As I understood it's a `shared_lock` and `Lock1` and `Lock2` lock the same `shared_mutex`. LockW will wait for Lock1 but Lock2 will succeed without waiting. – BJovke Apr 11 '18 at 14:13
  • @BJovke That's what I thought too, but because Lock1 and Lock2 are in the same thread, and Lock1 outlives Lock2, there's chance that the deadlock described above will occur... – Bill Kotsias Apr 11 '18 at 14:18
  • 1
    Your code has undefined behavior: `If lock_shared is called by a thread that already owns the mutex in any mode (exclusive or shared), the behavior is undefined.`. – SergeyA Apr 11 '18 at 14:34
  • It sounds like you calling a function that locks from within a function that has already acquired a lock? If so, that will not work, as pointed out by SergeyA. – ttemple Apr 14 '18 at 13:57

0 Answers0