PTHREAD_CANCEL_DEFERRED

David Xu davidxu at freebsd.org
Sat Aug 14 00:19:14 UTC 2010


Kostik Belousov wrote:
> On Fri, Aug 13, 2010 at 09:23:51AM +0000, David Xu wrote:
>   
>> David Xu wrote:
>>
>>     
>>>>> if you don't call testcancel() in close() stub like current libthr did,
>>>>> B won't response to the cancel request, you lost the race.
>>>>>           
>>>> This situation should be handled by my proposal, since SIGCANCEL is
>>>> delivered only
>>>> - at the syscall entry point
>>>> - at the syscall premature return
>>>> Userspace would not get SIGCANCEL at time of [1], instead, signal will
>>>> be delivered at [2].
>>>>         
>>> kernel may don't know if the syscall is cancelable, because it depends
>>> on usage, if the close() syscall is used by fclose(), then the syscall
>>> is not cancellation point, libc avoids this by using _close(),
>>> and libthr does not override it. if kernel knows when a thread is at
>>> cancellation point, then it needs another syscall to set and unset
>>> the flag, but that's too expensive and in practical it is not
>>> acceptable.
>>>       
> The kernel only decides whether to process SIGCANCEL specially. The
> decision about the cancel point is still at the hands of the threading
> library. The delivered SIGCANCEL goes through the same checks of
> eligibility for cancellation as before. But it is only delivered now at
> potential cancellation points for deferred case.
>
> Please see the patch at
> http://people.freebsd.org/~kib//misc/cancel_defer.1.patch
> for the proof of concept prototype.
>
>   
>> a bit out of topic, I also think that thread cancellation is not
>> better than a simple signal, because it does not return to caller
>> and force you to push and pop somethings, it may also be incompatible
>> with some language's exception handling, why does not just use
>> signal to interrupt syscall and let caller to check if the thread
>> should exit, the UNIX is quite good at this.
>>     
>
> This still does not give the answer of whether the syscall was executed.
> I have to check for %pc to see when the signal was delivered. Also, to
> be able to use signal in the way you suggested, I need a signal handler
> installed. This is very inconvenient from the library.
>
> BTW, I looked at the Solaris cancellation(5) man page, and it seems that
> Solaris implements the proper (from my POV) deferred cancellation:
> ==============
> When cancellation is deferred (the default case), cancellation occurs
> only within the scope of a function defined as a cancellation point
> (after the function is called and before the function returns).
> ==============
>   
while the above patch may work, there could have exceptions:

just before syscall close() enters kernel, a user signal is received, 
and the user
signal handler calls a syscall which happens to be cancellation point, I 
saw some
programs print a log in signal handler, and thread is canceled,
e.g write(2, msg, strlen(msg)) to log a message,
close() syscall is still not called, though it is arguable that if this 
signal handler
code is legal.

thread suspending in libthr uses SIGCANCEL to check suspending state,
the code needs to be adjusted, it seems I have to use another signal.



More information about the freebsd-threads mailing list