-
Notifications
You must be signed in to change notification settings - Fork 13.4k
sync::Semaphore needs to require nonnegative initial resource count #15758
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
Comments
to clarify: with semaphores initialized to 1, and used like mutexes (i.e. never signalled up to 2 or more), the behaviour is correct; all that would be required for that case is Dr-Emann found this bug on irc. |
Something a little tricky is going on here, I remember thinking about this last time I was looking at this code. The check I believe is correct in some situations, however. If you start out with a count of 1 and then immediately get 10 waiters, the count will be -9. When one of them releases a resource, the count is still negative after the bump (-8), but it definitely needs to signal someone. I think that negative initialization is indeed broken, however. |
Oh yes, now I remember. The implementation is correct but doesn't support negative initialization, but it fails to assert nonnegative (or require uint) in the constructor. What's going on is the waiters subtract from count unconditionally, so count actually represents the number of resources not already "spoken for" by existing waiters. The reason I chose this implementation is that it avoids needing to use
However even if you use while to solve this, you don't get bounded waiting since waiter 2 can still cut in line by racing this way. Subtracting from count before going to sleep "claims your spot in line" since it will force waiter 2 to also use the wait queue. Not to mention that since all this logic is interleaved with a raw pthread mutex I think the appropriate solution is just to assert in the constructor that the initial value is nonnegative -- the speed + bounded waiting benefits outweigh the obscure use case of negative initialization, since this is used as the building block for |
Semaphores are not currently designed to handle this case correctly, leading to very strange behavior. Semaphores as written are intended to count *resources* and it's not possible to have a negative number of resources. This alters the behavior and documentation to note that the task will be failed if the initial count is 0. Closes rust-lang#15758
Semaphores are not currently designed to handle this case correctly, leading to very strange behavior. Semaphores as written are intended to count *resources* and it's not possible to have a negative number of resources. This alters the behavior and documentation to note that the task will be failed if the initial count is 0. Closes #15758
https://github.com/rust-lang/rust/blob/master/src/libsync/raw.rs#L153
should be
@alexcrichton, please confirm
it looks like i introduced this by accident in 604e4ad? No idea what i was thinking.
edit: changed title; see below
The text was updated successfully, but these errors were encountered: