Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sync: confusing documentation for RWMutex #19460

Closed
Lexicality opened this issue Mar 8, 2017 · 11 comments
Closed

sync: confusing documentation for RWMutex #19460

Lexicality opened this issue Mar 8, 2017 · 11 comments
Labels
Documentation FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@Lexicality
Copy link

sync#RWMutex

An RWMutex is a reader/writer mutual exclusion lock. The lock can be held by an arbitrary number of readers or a single writer. RWMutexes can be created as part of other structures; the zero value for a RWMutex is an unlocked mutex.

An RWMutex must not be copied after first use.

If a goroutine holds a RWMutex for reading, it must not expect this or any other goroutine to be able to also take the read lock until the first read lock is released. In particular, this prohibits recursive read locking. This is to ensure that the lock eventually becomes available; a blocked Lock call excludes new readers from acquiring the lock.

The third paragraph "If a goroutine holds a RWMutex for reading, it must not expect this or any other goroutine to be able to also take the read lock until the first read lock is released." appears to contradict the first paragraph "The lock can be held by an arbitrary number of readers or a single writer."

After reading #7576 I think I understand this to mean that subsequent calls to RWMutex.RLock() will block if a call to RWMutex.Lock() has taken place (even if the write lock is currently not held), however that is not apparent from the rest of the documentation.

If this is the case can the forward for RWLock and the documentation for RWLock.RLock be updated to match please?

@ianlancetaylor ianlancetaylor added this to the Go1.9 milestone Mar 8, 2017
@ianlancetaylor ianlancetaylor changed the title sync: Confusing documentation for RWMutex sync: confusing documentation for RWMutex Mar 8, 2017
@ianlancetaylor
Copy link
Contributor

Pedantically, you say "subsequent calls to RWMutex.RLock() will block" but it would be more correct to say "subsequent calls to RWMutex.RLock() may block."

@Lexicality
Copy link
Author

Oh? Looks like I'm still confused then. 😛
It was my understanding that if you did something similar to this:

rw := sync.RWMutex{}
rw.RLock()
go rw.Lock()
rw.RLock() // :(

You would always* end up with a deadlock (*assuming 'favourable' scheduling)

@ianlancetaylor
Copy link
Contributor

I'm sorry, I misread your comment. I think you're right.

@gopherbot
Copy link

CL https://golang.org/cl/45697 mentions this issue.

@bradfitz
Copy link
Contributor

This was already fixed once in #15418 by b3f98d7.

I just tried to say more in https://golang.org/cl/45697 but it's unclear how much better my updated text is.

I'll let @ianlancetaylor or @dvyukov decide.

@bradfitz bradfitz modified the milestones: Go1.9Maybe, Go1.9 Jun 14, 2017
@bradfitz bradfitz added the NeedsFix The path to resolution is known, but the work has not been done. label Jun 14, 2017
@dvyukov
Copy link
Member

dvyukov commented Jun 14, 2017

The third paragraph "If a goroutine holds a RWMutex for reading,
it must not expect this or any other goroutine to be able to also take
the read lock until the first read lock is released." appears to contradict
the first paragraph "The lock can be held by an arbitrary number of
readers or a single writer."

Are you sure they are contradicting? What exactly is the contradiction?

@bradfitz
Copy link
Contributor

The contradiction is only in a world with no goroutines calling Lock.

It says "an arbitrary number of readers" or "a single writer".

The arbitrary number of readers part is actually true if there's no goroutine ever calling Lock. Then anybody's free to call RLock without fear of deadlocks. The deadlock only happens if anybody's calling Lock.

The CL I sent above the words:

... and another goroutine might call Lock, ...

@dvyukov
Copy link
Member

dvyukov commented Jun 14, 2017

@bradfitz right
the change looks +1 to me

@Lexicality
Copy link
Author

👍, though I still think RLock() should specify that it blocks.
Eg

RLock locks rw for reading. If another goroutine has or is trying to lock for writing, RLock blocks until the write has completed.

@dvyukov
Copy link
Member

dvyukov commented Jun 14, 2017

RLock may block until (at least for the "is trying to lock for writing" case)

@bradfitz
Copy link
Contributor

I've added a small note to the RLock method referencing the type comment. PTAL.

@golang golang locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Documentation FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

5 participants