Bug 113588
Summary: | NPTL pthread_mutex_destroy return EBUSY even if mutex is not locked... | ||
---|---|---|---|
Product: | Red Hat Enterprise Linux 3 | Reporter: | Umesh R. Patil <upatil> |
Component: | kernel | Assignee: | Arjan van de Ven <arjanv> |
Status: | CLOSED NOTABUG | QA Contact: | Brian Brock <bbrock> |
Severity: | medium | Docs Contact: | |
Priority: | medium | ||
Version: | 3.0 | CC: | drepper, petrides, riel, roland, upatil |
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | All | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2004-01-15 17:55:37 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
Umesh R. Patil
2004-01-15 16:39:08 UTC
I don't see anything wrong about this behaviour. http://www.opengroup.org/onlinepubs/007904975/functions/pthread_mutex_trylock.html says clearly that this program has undefined behaviour. Returning EBUSY from pthread_mutex_destroy on such a mutex is a conforming behaviour. You can use PTHREAD_MUTEX_ERRORCHECK mutex if you want to get an error from pthread_mutex_unlock and not undefined behaviour. However, http://www.opengroup.org/onlinepubs/007904975/functions/pthread_mutex_destroy.html indicates: "It shall be safe to destroy an initialized mutex that is unlocked. Attempting to destroy a locked mutex results in undefined behavior." In the example, the mutex is not locked. Also: "[EBUSY] The implementation has detected an attempt to destroy the object referenced by mutex while it is locked or referenced (for example, while being used in a pthread_cond_timedwait() or pthread_cond_wait()) by another thread." The mutex in the example is neither locked nor referenced by another thread. EBUSY shouldn't be returned in this case... That doesn't matter. Once your program hits undefined behaviour once, the standard doesn't cover anything in it any more. The implementation may choose to lock a mutex in pthread_mutex_unlock called on an unlocked mutex, format your disk or whatever else it decides. You have put the mutex in an undefined state by incorrectly calling pthread_mutex_unlock. Anything can happen after that. Stop arguing that you are so innocent and the bad implementation should help you poor developer. It's your fault alone, live with the consequences. If you cannot write correct code, use the error checking mutex type. Ulrich: The code given to you is a sample for reproducing the case and I am not arguing anything here. I was just pointing out what the spec says. Mutex unlocks are done in cleanup handlers so that an exiting thread, that hit a cancellation point, doesn't leave it locked. David Butenhof's book describes this mechanism in detail in Chapter 5 page 147!!! Your response here and elsewhere on the web are always rude and obnoxious. Looks like you get angry when someone points out problems in your poorly written code!!! You talk about bad implementation? You should start with NPTL because any reasonable implementation would have basic checks before putting a resource in a funny condition. Your stance is that if the "spec" doesn't say something - do something crazy (like format your disk - Thanks Jakub...) POSIX specifically has error checking mutexes which are supposed to do basic checks while normal mutexes are not required to do them for performance reasons. Slowing down all conforming code out there because of a few buggy programs is a bad idea. BTW: You can also use PTHREAD_MUTEX_RECURSIVE, which is required similarly to PTHREAD_MUTEX_ERRORCHECK to fail pthread_mutex_unlock if called on unlocked mutex. Mutex unlock in cleanup handlers can be written so that you never unlock an unlocked mutex. I am not implying that normal mutexes do more error checks in pthread_mutex_unlock. Getting an EBUSY led us down the path of trying to figure out where we were destroying a locked mutex when the problem was of a different nature with an extra pthread_mutex_unlock of an unlocked mutex. This was the right behavior for a normal mutex but the error code is misleading. In glibc's pthread_mutex_unlock.c, mutex->__data.__nusers becomes UINT_MAX when decremented from a value of 0 and pthread_mutex_destroy.c reports an EBUSY because mutex->__data.__nusers is ! 0. Would it make sense to prevent mutex->__data.__nusers from being decremented when it is zero? This way you don't break compliance with the spec, the error codes will be correct and undefined behaviors will remain what they are. This is just a suggestion since our code doesn't rely on this behavior... |