Re: GCC 4.6.2 C++ thread cancellation issue
|[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]|
On 15 May 2012 14:48, Mike Dalpee wrote: > > Of course, I realize this is likely the topic of much debate, and gcc's implemention is probably an attempt to be compliant with the evolving c++ standard. What evolving C++ standard? The forced-unwind stuff was designed and implemented years ago, before ISO C++ talked about threads, and even in the current C++ standard there is no support for thread cancellation (because there was no consensus how it should work.) The forced-unwind behaviour was an attempt to give sane semantics (for some value of sane) to something not covered by any standard (at the time, and still not covered now.) > But clearly, g++'s approach is highly flawed, so perhaps the standard needs to be driven in a way such that g++ can ultimately provide the Solaris-style thread cancellation semantics. Which are? It's hard to implement semantics that may or may not be publicly documented. There was a POSIX-C++ working group which discussed thread cancellation, but no consensus was reached and the working group stalled. On 15 May 2012 20:40, Mike Dalpee wrote: > Just to be clear, I am using pthread's synchronous cancellation feature - i.e., cancellation can only occur at known "cancellation points", which are places at which the thread is waiting to be rescheduled. So the cancellation is not asynchrounous with respect to thread execution. Understood. But pthreads is a C API, so by using it with C++ you're already writing non-portable code (it works well, almost invisibly, in most cases, unfortunately thread-cancellation is one of the places the non-portability show up.) > Stack unwinding/destructor excecution does occur in the Solaris C++ implementation from the scope enclosing the cancellation point. In my view, this behavior is required to compose a correctly running program. A very common approach to resource management in C++ programs is to use a constructor to "acquire" a resource and the destructor to "release" it. Since a thread is just one part of a running program, being able to cancel a thread without running destructors would be (and for me, is) very bad, as it would hang acquired resources out to dry (such as a mutex lock, for instance) with disastrous results (deadlocks). Indeed, which is why the GNU implementation uses an exception, as that already interacts nicely with all that lovely RAII code out there. That choice has other, sometimes undesirable, consequences though. > Again in my view, the use of catch(...) is an undesireable practice; if you need something to happen no matter how a scope is exitted (like Java's finalize), its much better to encapsulate that behaviour in an object's destructor. But, if catch(...) must be used, it should be oblivious to the pthread_cancellation mechanism. Othewise, you put it on the programmer to cooperate with your cancellation mechanism (like g++ does, requiring the "special" exception to be caught and rethrown), and if they do not do so unfailingly, then bad things will likely occur (like an abort, in the g++ case). It also means any vendor library that was developed without this requirement in mind would be completely unreliable when used in a threaded environment. Simply untenable. I think some of the reasoning for the GNU behaviour is that un-catchable exceptions are pretty nasty too. Making cancellation work as an exception (even if one that must be rethrown) allows some types of code to work, at the expense of other types of code. It's a tradeoff. The right choice might not have been made. > Anyway, I will do what you suggest and post the examples to bugzilla. Thanks again for your time and observations. Great, thanks for taking the time to debug and report the problems, that will help it be improved, even if it's not immediately.