Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Aug 2010 10:59:57 +0000
From:      David Xu <davidxu@freebsd.org>
To:        Kostik Belousov <kostikbel@gmail.com>
Cc:        freebsd-threads@freebsd.org
Subject:   Re: PTHREAD_CANCEL_DEFERRED
Message-ID:  <4C63D42D.8040606@freebsd.org>
In-Reply-To: <20100811204758.GQ2396@deviant.kiev.zoral.com.ua>
References:  <20100811204758.GQ2396@deviant.kiev.zoral.com.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
Kostik Belousov wrote:
> Hi,
> Let consider the thread in the state where the cancelation is enabled
> and cancelation mode set to the PTHREAD_CANCEL_DEFERRED.
> 
> SUSv4 says the following:
> Whenever a thread has cancelability enabled and a cancellation request
> has been made with that thread as the target, and the thread then
> calls any function that is a cancellation point (such as
> pthread_testcancel() or read()), the cancellation request shall be
> acted upon before the function returns. If a thread has cancelability
> enabled and a cancellation request is made with the thread as a target
> while the thread is suspended at a cancellation point, the thread
> shall be awakened and the cancellation request shall be acted upon.
> 
> Take the close(2) as example, and assume that the cancel is enabled
> for the thread in deferred mode. libthr wrapper around the syscall
> executes this:
> 
>      	curthread->cancel_point++;
> 	testcancel(curthread);
> 	__sys_close(fd);
> 	curthread->cancel_point--;
> 
> The pthread_cancel() sends the SIGCANCEL signal to the
> thread. SIGCANCEL handler calls pthread_exit() if thread has the
> cancel_point greater then 0.
> 
> I think this is not right. For instance, thread can be canceled due to
> SIGCANCEL delivery at the point after the return into the usermode
> from close(), but before cancel_point is decremented. IMO, the cited
> statements from the SUSv4 prohibit such behaviour. We should cancel
> either before closing fd, or during the sleep in close(), but then the
> syscall should be aborted ("as if signal is delivered"), and again fd
> should not be closed.
> 
> Actually, besides not being compliant, I think that the current
> behaviour is not useful, since in deferred case, we cannot know
> whether the action by the call that is cancelation point was performed
> or not.
> 
> This is not a rant, I probably will fix the issue if it is agreed
> upon. Opinions ?

it is true that a cancellation point does not return when cancellation
happens, so we really does not know if it did something or not,
and SUSv4 does not say cancellation point is an atomic transaction,
and whether it will rollback when cancellation happens, the problem may
happen even if you want to fix it, if the cancellation request is sent
after int 0x80 instruction returns (on i386) but before libc close()
stub returns, the cancellation still can happen, so could you tell
if the file handle is closed or not ? there is no way to tell
caller that the close() really did something.
I found the issue when I wrote the code, and it seems Linux does
it in same way, so I had not done further work on it.




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4C63D42D.8040606>