On Wed, Dec 31, 2008 at 01:42:44PM -0600, Jason King wrote:
> It's not clear from my reading of the man pages if port_get[n](3c) is
> an intention thread cancellation point. Looking at the cancellation
> implementation, it strongly suggests port_get[n] is a cancellation
> point (I'll probably test this sometime this weekend when I have a bit
> more time to mess with things). Assuming my suspicions are correct,
> can anyone tell me if this is in fact intended (would seem logical)
> and if it's merely a documentation lapse (i.e. I can depend on this
> behavior)?
I don't know the answer (more below) to your question, but I had a
similar question a while back about port_*() being async-signal-safe. I
talked to ARC members and they agreed that it was and should be, and so
I simply filed a manpage bug to have the manpage corrected.
I believe most system calls should be cancellation points. In fact,
cancellation(5) strongly implies it! For example, cancellation(5) says:
Typically, any call that might require a long wait should be
a cancellation point. Operations need to check for pending
cancellation requests when the operation is about to block
indefinitely. ...
(Yes, that's advice to application developers about their functions
"that might require a long wait," but you'd think that the operating
systems' developers ought to follow their own advice, at least with
respect to system calls.)
and
... (Because
a cancellation is pending, a call to a cancellation point
such as read(2) or write(2) would also cancel the caller
here.)
It also lists system calls that are intended to be cancellation points,
but the manpages for those system calls do not mention thread
cancellation.
Time to look at how thread cancellation works. Ah, well, it looks like
system calls that are cancellation points need to either be defined in
$SRC/lib/libc/port/threads/scalls.c (so as to make use of macros like
"PROLOGUE" defined in scalls.c) or need to call _cancel_prologue() and
_cancel_epilogue(). Evidently _portfs() does not, and neither do any of
the port_*() functions. So I'm not sure if port_get*() really are
cancellation points. But IMO they ought to be.
Nico
--