pthreads-hackers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pthreads-hackers] pthreads and cancellation


From: Marcus Brinkmann
Subject: [Pthreads-hackers] pthreads and cancellation
Date: Fri, 25 Jan 2002 22:04:17 +0100
User-agent: Mutt/1.3.25i

Hi,

I think I found a design flaw in the current pthreads implementation
concerning conditions and cancellation.

The standard has (among others) two requirements:
1. A condition can be destroyed if there are no waiters on it.
2. A cancelled thread that is unblocked from a condition wait shall not
   consume the condition signal.

The first requirement allows this sequence:
pthreads_mutex_lock      (the mutex belonging to the condition)
pthreads_cond_broadcast  (make it so that there are no waiters)
pthreads_cond_destroy    (now we can destroy it)
pthreads_mutex_unlock    (let others in)

The second requirement prevents a race where a condition_signal can get lost
if the thread woken up is canceled at the same time.

The current implementation in sysdeps/generic and sysdeps/mach is easy to
describe:  All threads waiting for a condition are in a linked list.  The
blocking is done by a mach_msg_recv.  The wakeup by a dequeue and
mach_msg_send.  It has two races, though, in the following case:  The
waiting thread is canceled while it also receives a signal.

The waiting thread can be canceled just before it receives the signal.
Then it will try to lock the condition to check if it is still on the queue. 
The problem is that the condition might be destroyed already.  On the other
hand, we can not check SELF->prevp without locking the condition, as
manipulating the condition queue accesses SELF->prevp.

The waiting thread can be canceled just after the signal is send to it (and
it is dequeued from the waiter queue).  The above race also applies here,
and in addition the following problem occurs:  We must not consume the
signal.  But as the signal is just a message to our message port, we have to
consume it.  To make up for it, the current code just signals the condition
again.  But this requires that we access the condition, which might have
been destroyed already.

Both problems don't appear to be trivial to me.  The first requires that we
can identify if a thread is on a list of which we don't even know if it
still exists.  The second appears to be more serious:  Fundamentally, when
we received the signal we can not resignal it, because we are not on the
condition list and so we don't know if it still exists.  Maybe we can fix
both with a global lock.  Without a way to for the thread to keep track if
the condition still exists or not, I can only imagine a solution that
requires the thread to reply to a condition signal, and notify the sender
if it is consumed or not.

Thanks,
Marcus


-- 
`Rhubarb is no Egyptian god.' Debian http://www.debian.org address@hidden
Marcus Brinkmann              GNU    http://www.gnu.org    address@hidden
address@hidden
http://www.marcus-brinkmann.de



reply via email to

[Prev in Thread] Current Thread [Next in Thread]