Prev: Xlib question - efficient way to get pixel value?
Next: Printing Back tracing information during run time
From: Noob on 28 Oct 2009 09:27 [ Cross-posted to c.p.t and c.u.p ] Hello, I'm using a proprietary library (no source code) which requires the user to provide 4 mutex-related functions (create, delete, lock, unlock). AFAICT, if I were using a POSIX OS, I could make trivial wrappers around pthread_mutex_init pthread_mutex_destroy pthread_mutex_lock pthread_mutex_unlock But this library has specific requirements for the delete function: If delete is called on a locked mutex, the function must return an error code to signal the error to the function's caller. However, the documentation for pthread_mutex_destroy explicitly states: http://www.opengroup.org/onlinepubs/009695399/functions/pthread_mutex_init.html """ It shall be safe to destroy an initialized mutex that is unlocked. Attempting to destroy a locked mutex results in undefined behavior. """ This means that my delete function can't just call pthread_mutex_destroy because I would invoke UB if the mutex is locked, and I wouldn't be able to return the requested error code, right? So... Does this mean I have to keep track whether the mutex is locked? (It would appear so.) Or perhaps I could mess with the OS code? (shudder) I'd like to tell the library author that it is unreasonable to impose overhead on every lock and unlock operation just to catch an obvious (?) programming error on delete. What do you think? N.B. the library requires mutex with recursive semantic. Regards.
From: David Schwartz on 28 Oct 2009 10:29 On Oct 28, 6:27 am, Noob <r...(a)127.0.0.1> wrote: > But this library has specific requirements for the delete function: > > If delete is called on a locked mutex, the function must return an error > code to signal the error to the function's caller. That is, IMO, fundamentally busted behavior, unless it only means locked by the calling thread. > This means that my delete function can't just call pthread_mutex_destroy > because I would invoke UB if the mutex is locked, and I wouldn't be able > to return the requested error code, right? > > So... Does this mean I have to keep track whether the mutex is locked? > (It would appear so.) > Or perhaps I could mess with the OS code? (shudder) > > I'd like to tell the library author that it is unreasonable to impose > overhead on every lock and unlock operation just to catch an obvious (?) > programming error on delete. What do you think? > > N.B. the library requires mutex with recursive semantic. Since the mutex is recursive, one of two things are the case: 1) The requirement only applies if the calling thread holds the lock on the mutex, in which case you have to keep track of the lock count anyway. (Otherwise, how would you know what to do in the unlock operation?) The library is being reasonable, though quirky. 2) The requirement applies even if another thread holds the mutex. This is a real pain to implement, and the requirement is fundamentally busted. DS
From: Noob on 28 Oct 2009 11:04 David Schwartz wrote: > Noob wrote: > >> But this library has specific requirements for the delete function: >> >> If delete is called on a locked mutex, the function must return an error >> code to signal the error to the function's caller. > > That is, IMO, fundamentally busted behavior, unless it only means > locked by the calling thread. Could you expand on /why/ you think it is busted behavior? (I need ammo to try to convince the library authors.) The exact requirements are: 1) Return an error when attempting to delete "a mutex currently owned by another thread". 2) Return an error when attempting to delete "a mutex currently owned by the calling thread". NB: by "owned" I assume they mean "locked". Since a locked mutex is so either by the calling thread, or by another thread (duh!) it seems the two requirements boil down to: Return an error (and, I assume, leave the mutex alone) when attempting to delete a locked mutex. >> This means that my delete function can't just call pthread_mutex_destroy >> because I would invoke UB if the mutex is locked, and I wouldn't be able >> to return the requested error code, right? >> >> So... Does this mean I have to keep track whether the mutex is locked? >> (It would appear so.) >> Or perhaps I could mess with the OS code? (shudder) >> >> I'd like to tell the library author that it is unreasonable to impose >> overhead on every lock and unlock operation just to catch an obvious (?) >> programming error on delete. What do you think? >> >> N.B. the library requires mutex with recursive semantic. > > Since the mutex is recursive, one of two things are the case: > > 1) The requirement only applies if the calling thread holds the lock > on the mutex, in which case you have to keep track of the lock count > anyway. (Otherwise, how would you know what to do in the unlock > operation?) The library is being reasonable, though quirky. The OS I'm using provides recursive mutex. Therefore, I don't think I have to deal with lock counts, as the OS takes care of that. Unless I need to know in delete whether the mutex is locked. Trying to delete a locked mutex sounds like a serious programmer error. Mutex destruction (and creation) should be done in well-defined parts of the application, when one can be sure the mutex is not in use anymore, right? > 2) The requirement applies even if another thread holds the mutex. > This is a real pain to implement, and the requirement is fundamentally > busted. According to the library's spec, delete may be called at any time, by any thread, and it is the user's responsibility to return an error and leave the mutex untouched if the mutex is currently locked... Regards.
From: Eric Sosman on 28 Oct 2009 11:40 Noob wrote: > David Schwartz wrote: > >> Noob wrote: >> >>> But this library has specific requirements for the delete function: >>> >>> If delete is called on a locked mutex, the function must return an error >>> code to signal the error to the function's caller. >> That is, IMO, fundamentally busted behavior, unless it only means >> locked by the calling thread. > > Could you expand on /why/ you think it is busted behavior? > (I need ammo to try to convince the library authors.) > > The exact requirements are: > > 1) Return an error when attempting to delete "a mutex currently owned by > another thread". This is broken, period. Suppose thread T1 tries to delete the mutex and discovers (somehow) that it is locked by T2. T1 leaves the mutex alone, the deletion attempt returns an error, and all is well. But suppose T1 comes along at a moment when the mutex is unlocked, and succeeds in deleting it. Two clock cycles later, T2 tries to lock the destroyed mutex, and the fertilizer hits the fan. The fact that T1 found the mutex unlocked is no proof that the mutex is "unused," or that T2 might not attempt to use it again. If T1 deletes a mutex that T2 might still want to use, the application is broken. If T1 can find the mutex locked by T2, it must be the case that T2 still wants to use it. Therefore the mere possibility that delete-while-locked-elsewhere could occur is proof that the design is broken. > 2) Return an error when attempting to delete "a mutex currently owned by > the calling thread". This isn't quite as clear-cut, but it still seems dubious. > [...] > Trying to delete a locked mutex sounds like a serious programmer error. Yes, but the point is more general: Trying to delete an "in use" mutex is a serious programmer error. A mutex in the locked state is obviously in use, but it is a mistake to reason that a mutex in the unlocked state is not in use. > According to the library's spec, delete may be called at any time, by > any thread, and it is the user's responsibility to return an error and > leave the mutex untouched if the mutex is currently locked... Broken. The danger isn't when deletion fails because the mutex is locked, but when deletion succeeds because the mutex is unlocked -- but is still in use. -- Eric.Sosman(a)sun.com
From: Måns Rullgård on 28 Oct 2009 12:50
David Schwartz <davids(a)webmaster.com> writes: > On Oct 28, 6:27�am, Noob <r...(a)127.0.0.1> wrote: > >> But this library has specific requirements for the delete function: >> >> If delete is called on a locked mutex, the function must return an error >> code to signal the error to the function's caller. > > That is, IMO, fundamentally busted behavior, unless it only means > locked by the calling thread. I agree. I wouldn't go anywhere near that library. Find another one written by someone with half a brain. That said, you could use pthread_mutex_trylock() to find out whether or not the muxtex is locked. -- M�ns Rullg�rd mans(a)mansr.com |