symc.RWMutex docs include a perplexing note

The GoDoc for sync.RWMutex includes the folowing note:

If a goroutine holds a RWMutex for reading, it must not expect this or other goroutine to be able to also take the read lock until the first lock is released.

My read of this is that once a goroutine takes the read lock then no other goroutine can also take it until the first one releases it. This can’t be correct because that would defeat the purpose of the RWMutex. But I can’t figure out which part of the sentence I am misinterpreting.

I read this as “it must not take for granted…”.

In the cited context, I would conclude that when a goroutine holds a read lock on a mutex, other goroutines may fail taking another read lock of this mutex.

The cited documentation goes on by saying this shall prevent recursive read locks.

However, the source does not seem to impose any restrictions on other readers, unless I have missed something. The only thing that I see there that can block further readers is a pending write lock.

Maybe the doc comment is not in sync with the actual code…?

It says that you can’t assume that just because you have a read lock someone else will also be able to get one, or even you yourself recursively. The reason for this is that a goroutine that is blocked waiting for a write lock also blocks new read locks - otherwise it could be starved forever.

In most cases you will of course be able to get a read lock while it’s already read locked. But you can’t depend on that being the case for correctness.

1 Like

Ah, that makes a lot more sense! I wish the note was clear about that. This would be much better:

Holding a read lock will block any attemts to take a read lock that happen after a goroutine gets blocked waiting for a write lock on the same RWMutex until the write lock is obtained and released. This prevents starvation of coroutines attemting to get write locks.

But if you get that specific you exclude all the situations you are not mentioning. :wink: Now it sounds like I’ll get the read lock once someone else has taken and released a write lock - but there could be another write lock waiting to prevent me, etc. The current docs just tells you what not to depend on.

Drat, you are right. How about this:

Although read locks on a RWMutex can be held by multiple goroutines simultaneously, goroutines attempting to take one will be blocked by any attempts to take a write lock on the same RWMutex until all such write locks attempted before their attempt to take the read lock have been released.

I don’t know, sounds complicated to me and doesn’t say more than what’s there today, really. But open an issue if you feel strongly about it I guess. :slight_smile:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.