First, let me say I'm excited to see that 10.5 has sleep(), read(), etc. as cancellation points. This makes life a lot easier :) (If anyone has a complete list of cancellation points for 10.5, please let me know -- the man page had an inaccurate list in 10.4, and is unchanged in 10.5, so I don't trust that it's completely accurate either)
However, my main question is regarding the cleanup of C++ destructors on the stack following a thread cancellation. For example, I have attached a bit of sample code in which the thread's launch function instantiates a class ("Foo") and sleeps, and then the main thread calls pthread_cancel on it.
On Mac OS 10.5.1, I get: $ g++ -o test test.cc -lpthread -Wall && ./test launched cancelling waiting
Note the lack of any kind of message from Foo's destructor...
On linux (kernel 2.6.21.5-P4), I get: $ g++ test.cc -o test -lpthread -Wall && ./test launched cancelling waiting Foo was cancelled catch-all exception handler
This seems like a good solution that I would like to see on OS X; the stack is unwound using the well-established exception mechanism, allowing object destructors to cleanup after themselves ("Foo was cancelled"), and allowing generic exception handling to cover both regular exceptions as well as a thread cancel ("catch-all exception handler").
Under the current Darwin/OS X implementation, if I use a std::vector in a thread that is cancelled, it's going to leak its memory because its destructor never gets called. Or in my own classes such as a scope-limited mutex lock, the mutex would never be released. (If I was in a critical section where that would be a bad thing, I could change the thread cancel state, but I almost always want to be cancelable but automatically release mutexes on the way out.)
Any ideas how I can get a workaround? For instance, uncommenting the two pthread_cleanup statements in the attached test case causes std::terminate to be called on both platforms... throwing an exception during cancellation is a no-no (understandable on linux (can't throw exceptions during an exception unwind), but unfortunate in the current OS X implementation since it apparently isn't doing C++-aware stack unwinding anyway)
Thanks! -ethan
|