slamb.org / projects  

Thread cancellation tests

$Id: index.xml 1445 2006-05-04 21:57:43Z slamb $

POSIX thread cancellation (a.k.a. pthread cancellation) is a fairly new feature that so far is implemented extremely badly in most systems. These are a bunch of test programs I've written for checking behavior on different systems and submitting bug reports.

Please note that I'm not sure about all of these tests, so it's possible a platform may have correct behavior and still fail a test. But these test for the behavior my software currently expects. If you disagree with a test, please let me know.

Tested platforms

These are all the platforms I have tested to date:

Test results

test Linux + NPTL LinuxThreads OS X Digital Tru64 HP-UX FreeBSD Solaris cygwin
Basic functionality
This basic behavior is absolutely mandated by the Single UNIX Specification version 3. it should pass on every platform.
cancellation_disable pass[1] pass pass pass pass pass pass pass
cancellation_enable pass pass fail pass pass pass pass pass
cancellation_returnvalue pass pass fail pass pass pass pass pass
C++ behavior
These are not required by any specification, but are necessary to pass for usable C++ support. C++ should be the language of choice for using thread cancellation, since most code uses exception safety patterns that make cancellation safety trivial.
cancellation_exception pass[1] fail fail pass fail fail fail[6] fail
cancellation_while_throwing fail pass[2] pass[2] fail pass[2] pass[2] pass[2] pass[2]
Signal interaction
These are loosely described by the standards. For code to be able to receive both cancellation requests and signals safely, it should implement kqueue() or pass at least one of these tests.
cancellation_in_sighandler fail[3] fail[3] fail fail fail fail fail[3] fail
siglongjmp_cleanup fail fail fail fail fail fail fail fail
ucontext
The behavior here is not mentioned by the Single UNIX Specification version 3. It is useful for writing cancelable exception-safe C++ code around non-cancelable C libraries such as OpenSSL. See my atoms code for a thorough example.
swapcontext_before_cleanup pass pass na[4] pass pass fail[8] pass[7] na[4]
swapcontext_in_cleanup pass pass na[4] pass pass fail[8] pass[7] na[4]
Mandatory cancellation points
The Single UNIX Specification version 3 specifies a number of mandatory cancellation points; essentially every standardized blocking system call, as it is not possible to use cancellation well without support in these calls.
cancelpoint_nanosleep pass pass fail pass pass pass pass pass
cancelpoint_read pass pass fail fail[3] pass pass pass fail
cancelpoint_select pass pass fail pass pass pass pass fail
cancelpoint_write pass fail pass[5] pass pass pass pass fail

[1] - Previous versions failed this test.

[2] - It would be very surprising if this failed, given that this platform does not implement cancellation requests as C++ exceptions.

[3] - This test sometimes passes; the platform contains a race condition.

[4] - This test requires a feature which is not implemented on this platform.

[5] - The write() test on OS X passes, but this is almost certainly a false report caused by the test_cancellation_enable failure.

[6] - Solaris with the -mt compiler option appears to invoke C++ destructors but not catch clauses.

[7] - Solaris/sparc fails to compensate for the stack growing down, but this is easily worked around.

[8] - FreeBSD returns error from getcontext(), before I do anything interesting with cancellation. It appears the ucontext functions are totally broken on FreeBSD/alpha.

Conclusion

Don't use thread cancellation. It doesn't work, and it isn't likely to any time soon. If you need a thread cancellation mechanism, I recommend implementing one with sigsafe rather than using the (poorly) standardized mechanism.

Download

You can download the entire suite of tests here: cancellation-tests-0.1.0.tar.gz.