From: Måns Rullgård on
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
=?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
"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
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
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