From: Chris M. Thomasson on

"Noob" <root(a)127.0.0.1> wrote in message news:hcbsu6$ocf$1(a)aioe.org...
> Chris M. Thomasson wrote:
>
>> 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
>
> Thanks Chris, I'll take a hard look at it.

Here is updated code which handles the case in which a thread tries to
unlock a mutex that is locked by another thread:


http://cpt.pastebin.com/f3044e915


It also fixes a race-condition I overlooked. The unlocking needs to be done
under the protection of the hash lock. The previous code did not do this,
which would allow a thread A to destroy the mutex just before a thread B
unlocked it.

Sorry about that non-sense!


Anyway, I cannot seem to find any more issues.




> Please note that, although I was discussing this topic in light of a
> POSIX OS, the proprietary OS I'm using (ST OS21) does not conform to
> POSIX, AFAIK.

I am not sure as I am not really familiar with at operating system.

From: Chris M. Thomasson on
"Chris M. Thomasson" <no(a)spam.invalid> wrote in message
news:hccn64$fi5$2(a)news.eternal-september.org...
>
> "Noob" <root(a)127.0.0.1> wrote in message news:hcbsu6$ocf$1(a)aioe.org...
>> Chris M. Thomasson wrote:
>>
>>> 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
>>
>> Thanks Chris, I'll take a hard look at it.
>
> Here is updated code which handles the case in which a thread tries to
> unlock a mutex that is locked by another thread:
>
>
> http://cpt.pastebin.com/f3044e915
>
>
> It also fixes a race-condition I overlooked. The unlocking needs to be
> done under the protection of the hash lock. The previous code did not do
> this, which would allow a thread A to destroy the mutex just before a
> thread B unlocked it.
>
> Sorry about that non-sense!
>
>
> Anyway, I cannot seem to find any more issues.

I have implemented the algorithm in Relacy Race Detector:


http://relacy.pastebin.com/f227e4245


Relacy likes it! So, this scheme works. BTW, what does the interface look
like for the ST OS21 operating system? If it's compatible, then you have a
complete solution which will conform to the libraries rules.

From: David Schwartz on
On Oct 29, 5:42 am, Rainer Weikusat <rweiku...(a)mssgmbh.com> wrote:

> A more probable conjecture would be that the library uses the
> delete-operation to detect if a mutex has meanwhile been unlocked
> without blocking on it and another conjecture based on that and a
> short search of the as-always-inaccessible relevant documentation[*]
> would be that (at least some versions of) Windows behaves in this way.

I don't see how that could make sense. What if the mutex has meanwhile
been unlocked but another thread is about to lock it? How do you
guarantee that this other thread doesn't lock some other mutex?
(Unless you add all the other crufty requirements, like that a mutex
handle cannot be a pointer and that they cannot be re-used.)

DS
From: Rainer Weikusat on
David Schwartz <davids(a)webmaster.com> writes:
> On Oct 29, 5:42�am, Rainer Weikusat <rweiku...(a)mssgmbh.com> wrote:
>
>> A more probable conjecture would be that the library uses the
>> delete-operation to detect if a mutex has meanwhile been unlocked
>> without blocking on it and another conjecture based on that and a
>> short search of the as-always-inaccessible relevant documentation[*]
>> would be that (at least some versions of) Windows behaves in this way.
>
> I don't see how that could make sense. What if the mutex has meanwhile
> been unlocked but another thread is about to lock it? How do you
> guarantee that this other thread doesn't lock some other mutex?

Because there are is one thread with a mutex or maybe n threads with
mutexes and one 'master thread' 'watching' them (or something similar
with clearly separated 'kinds of threads'). That's a possible
arrangement where the delete-semantics would make (some) sense. Other
arrangements are conceivable but people usually write code to
accomplish something definite and not because they are out of their
senses (often both to a degree, actually -- once something has
been implemented, it is all too clear how it should have been done
instead :->, but 'it works' is a very practical quality).
From: Chris M. Thomasson on
"David Schwartz" <davids(a)webmaster.com> wrote in message
news:6b9a4262-aaab-4ea4-9fa0-56d98ae49f58(a)g22g2000prf.googlegroups.com...
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.

Indeed. The hack I posted also requires that the memory which makes up a
mutex cannot be freed. However, one can definetely use reference counting
with strong thread saftey to handle this senerio:
_________________________________________________________
struct foo
{
mutex m_lock;
// [...];
};


static global_ptr<foo> g_foo;


void threads()
{
for (;;)
{
local_ptr<foo> l_foo(g_foo);

if (! l_foo)
{
l_foo = new foo;
l_foo = g_foo.swap(l_foo);
}

l_foo->m_lock.lock();
l_foo->m_lock.unlock();

g_foo = NULL;
}
}
_________________________________________________________




`foo' objects are allowed to be dynamically created and destroyed on the
fly. Threads don't actually need to care about lifetime management because
the reference count handles all of that for them. Although, I have to say
that a library which has rules that basically demand using this type of
reference counting is pretty darn crappy.