-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
libstd Mutex can cause POSIX undefined behavior #31936
Comments
From later in the document:
That's interesting, do Rust's supported platforms follow that recommendation? I guess in that case leaking the guard would end up leaking the mutex as well. |
Glibc appears to check and return Leaking in this case is trivial anyway, because it only wants to invalidate that |
Bah oh well. I suspect that the undefined behavior here is written in with the intention of not wanting to specify what it means to unlock a destroyed mutex. As in the specific failure mode for us is that we destroy a locked mutex but still guarantee that it will never be used again. I suspect this is probably not a problem in practice, but would be good to handle nonetheless! We can likely just get away with a flag that indicates whether the lock has any active holders or not and we just avoid calling the destroy function if so. If @tomjakubowski is right though we can probably just close this or maybe fix a debug assertion in the destructor. |
OS X is also in the "returns EBUSY if locked, doesn't actually need to free resources anyway" camp: see pthread_mutex_destroy. musl's |
The Windows api also has a comment about destroying a locked mutex, but it seems to refer only to undefined-ness of other active users of the same mutex. (Requires a Windows-savvy developer to do the real interpretation though). |
To quote MSDN "SRW locks do not need to be explicitly destroyed." and since we use SRW locks for |
Dropping a mutex does call |
It just says "If a critical section is deleted while it is still owned, the state of the threads waiting for ownership of the deleted critical section is undefined." |
Oh, we do use critical sections for the fallback implementation, but that only occurs on Windows XP and older. Also when we destroy a mutex we know nobody is currently waiting for ownership, as clearly we can only destroy it when there are no other owners. If another thread has leaked the guard, it isn't waiting for ownership so that sentence doesn't apply to it. |
And it's only XP, not much to worry about! |
Android's bionic implementation also looks harmless: pthread_mutex.cpp |
It sounds like there's nothing to be done here. Can we close this? |
Not sure if anything needs to be done about this, since I don't know of any actual implementations having a problem with it, but it occurred to me when thinking about moving mutexes.
On Unix,
Mutex::new
corresponds to initialization withPTHREAD_MUTEX_INITIALIZER
;Mutex::lock
, which returns aMutexGuard
, corresponds topthread_mutex_lock
;MutexGuard::drop
corresponds topthread_mutex_unlock
; andMutex::drop
corresponds topthread_mutex_destroy
.If a
MutexGuard
is forgotten:...then we call
pthread_mutex_destroy
without first callingpthread_mutex_unlock
. The POSIX spec says:The text was updated successfully, but these errors were encountered: