Re: [SPAM] - [c++-pthreads] Re: [SPAM] - FW: RE: [c++-pthreads] Re: I'm Lost - Email found in subject - Email found in subject
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [SPAM] - [c++-pthreads] Re: [SPAM] - FW: RE: [c++-pthreads] Re: I'm Lost - Email found in subject - Email found in subject



I'm just saying that an application programmer who has a need to
cancel threads, and is willing to take the trouble to make sure
all the code in the cancellable thread is safe for use with
cancellation, could just as well "roll his own" solution, and then
will know for certain what is the overhead and how it will work.

In a single-threaded POSIX/UNIX application, the only standard way
to break it out of a catonic state is via a signal.  Therefore,
potentially blocking POSIX calls can return EINTR when a thread
receives a a signal and the signal is succesfully handled.  IFAIK,
every blocking call that POSIX guarantees will be interrupted by
pthread_cancel can also be interrupted by signals.

Although many (most?) programmers seems to ignore this fact, fully
conformant code is suppose to have recovery logic for every one of
these interruptible system calls, that will either retry the call
or take other appropriate action if the call returns prematurely
due to interruption.

I'm just saying that this recovery code provides a natural place
to insert application-specific polling for a request that the
thread cancel itself.  Another thread can post such a "die"
request in a volatile global variable before using pthread_kill to
send a signal to a given thread.  The thread will notice this
at the next point where it polls for a "die" request.

As you imply, the code must deal with a window between the thread
polling the "die" variable and the thread doing the blocking call,
during which a signal might come in and not wake up the thread.
You can get around the race problems pretty simply if the changes
to the "die" request variable monotonic, which will be the case if
you insist that a once-cancelled thread must terminate.  With this
simplification you can also provide a binary "ack" variable that
is set by the target thread once it has recognized that it has
been told to die.  The killer thread has to periodically retry the
pthread_kill() until the target thread acknowledges.

By the way, even if this seems ugly, it may not too far from what
your friendly C-language implementation of pthread_cancel is
doing.  In fact, I suspect that is why POSIX defined thread
cancelation as being a one-shot thing.

--Ted


On Wed, Jul 27, 2005 at 09:20:51PM +0200, Alexander Terekhov wrote:
> 
> Ted Baker wrote:
> [...]
> > Of course, polling won't help with cases where a thread is stuck
> > on a blocking system call, but then one does
> > have (dare I say it?)  pthread_kill().
> 
> You mean EINTR "cancellation" hack? You'd need a pselect()-like 
> logic and sigmask arguments
> 
>    If sigmask is not a null pointer, then the pselect() function 
>    shall replace the signal mask of the caller by the set of 
>    signals pointed to by sigmask before examining the descriptors, 
>    and shall restore the signal mask of the calling thread before 
>    returning.
> 
> added to all blocking system calls to make that castrated 
> "cancellation" really work (not being subject to a race with 
> respect to reaching interruptible state and signal delivery).