Prev: Xlib question - efficient way to get pixel value?
Next: Printing Back tracing information during run time
From: Måns Rullgård on 28 Oct 2009 15:57 scott(a)slp53.sl.home (Scott Lurndal) writes: > =?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= <mans(a)mansr.com> writes: >>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. >> > > My first thought too, use _trylock in the delete function. However, > that won't work for recursive mutexes, because it won't fail if the > current thread has the mutex. Then don't use recursive mutexes. Using recursing mutexes is also a strong indicator of design flaws. -- M�ns Rullg�rd mans(a)mansr.com
From: Scott Lurndal on 28 Oct 2009 18:03 =?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= <mans(a)mansr.com> writes: >scott(a)slp53.sl.home (Scott Lurndal) writes: > >> =?iso-8859-1?Q?M=E5ns_Rullg=E5rd?= <mans(a)mansr.com> writes: >>>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. >>> >> >> My first thought too, use _trylock in the delete function. However, >> that won't work for recursive mutexes, because it won't fail if the >> current thread has the mutex. > >Then don't use recursive mutexes. Using recursing mutexes is also a >strong indicator of design flaws. > Talk to the vendor of the proprietary library used by the OP. They're the ones that require recursive mutexes - I don't believe they should be used either. scott
From: Chris M. Thomasson on 28 Oct 2009 18:17 "Noob" <root(a)127.0.0.1> wrote in message news:hc9t7d$8c1$1(a)aioe.org... > Eric Sosman wrote: > >> 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. > > Except that one is left to wonder why T1 ever thought it would be a good > idea to delete the mutex... > >> 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 library also requires "return an error when attempting to lock an > uninitialized mutex". > > I don't know what they do in that library... Perhaps this explains why > they do not provide the source code. [...] Man! This sucks!! Anyway, I believe you could meet all the requirements, however, it's not going to be pretty. Here is what I hacked together for you so far: http://cpt.pastebin.com/f540aaef5 This is crowbar proof except for the case when a thread unlocks a mutex that it did not previously locked. This can be handled, but it will add even more overhead. All other cases are handled gracefully. Please take a look at the sample application. It should compile for you. I create N threads which sit in a loop and basically create, lock, unlock and destroy a global mutex. Conflicts are resolved by using a reference count and external hash lock table. Please study the code and tell me if it works for that nasty library you have to work with.
From: David Schwartz on 28 Oct 2009 20:55 On Oct 28, 8:04 am, Noob <r...(a)127.0.0.1> wrote: > >> 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.) Either they rely on this behavior or they don't. If they don't rely on it, why do they make you implement it? If they do rely on it, what happens when one thread destroys a mutex a split-second before another thread acquires it? The only way to make that sensible is to insist you detect an attempt to lock a destroyed mutex. However, think about what this means. It means you can never, ever reuse a mutex's identifier. It means a mutex cannot be a pointer to a structure that is freed when that mutex ceases to exist. Basically, it means the library plans to use a mutex among threads that cannot even agree on the lifespan of the mutex, and that's nonsensical because, among other reasons, they have to agree on the lifespan of what the data protects anyway. > 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. Even if it's locked by the calling thread? > > 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. It's not his fault you're using mutexes that don't provide his semantics when his semantics are reasonable. If he had a requirement that was specific to a mutex held by the calling thread for a recursive mutex, the semantics would be reasonable (ignoring the silliness of recursive mutexes to begin with) though odd. Your best bet would be to use non-recusive mutexes (if available, otherwise, use recursive mutexes but don't use them recusively) and implement the recursion yourself. It's not unusual to need different recursion semantics and have to implement your own recursion even when the platform supplies recursive mutexes. For example, someone might insist on reader/writer mutexes where the write lock was recursive. That's not totally unreasonable, but likely your platform doesn't provide them, so you would have to do code it yours. > Trying to delete a locked mutex sounds like a serious programmer error. If it's locked by another thread, it must be. If it's locked by the calling thread, it could be defined either way by the mutex semantics. Some typical mutexes either say it will succeed and delete the mutex (sort of unlocking it), some say it is undefined. Requiring specific behavior in this case is a somewhat bad thing because it means custom code will be needed in an operation that is best handled by the platform's optimized code. As you see, asking for special semantics when another thread holds the mutex is fundamentally busted. > 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? Well, it depends on the way you use mutexes. You can have mutexes associated with objects dynamically created and destroyed all over the place. But this will not work out sanely unless an "outer synchronization" protects the public visibility of objects. Create object with mutex, acquire global mutex, make object visible to other threads. Acquire global mutex, find object, lock object, remove object from collection, unlock global mutex, unlock object, delete object. That kind of thing. > > 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... This will require giving each mutex a 64-bit identifier that is looked up in a global hash table protected by a global mutex. Mutex identifiers can never be reused. YUCK! DS
From: Eric Sosman on 28 Oct 2009 22:26
Noob wrote: > [...] > I have no such freedom. I must use that proprietary library. > It is a MAFIAA requirement (DVB Conditional Access). The only MAFIAA references I find are to the merger of the Motion Picture Association of America (MPAA) with the Recording Industry Association of America (RIAA) to form the Music And Film Industry Association of America (MAFIAA). The merger was announced on April First, 2006. The date and the acronym suggest some amount of spoofery ... And DVB must be either the Democratic Voice of Burma or something to do with Victoria Beckham, aka Posh Spice. -- Eric Sosman esosman(a)ieee-dot-org.invalid |