My thread implementation uses the pimpl idiom, and in the Impl class, I have one version for each supported OS, as well as one that uses boost, so I can decide which one to use when creating the project.
I decided to make two classes: one is Thread, which has only the basic services provided by the OS; and the other is SafeThread, which inherits from Thread and has a shared interrupt method.
Thread has a terminate () method that performs intrusive termination. This is a virtual method that is overloaded in SafeThread, where it signals an event object. There is a (static) yeld () method, which from time to time should call the current thread; this method checks whether the event object is signaled, and, if so, throws an exception caught on the calling side of the stream entry point, thereby terminating the stream. When he does this, he signals the second event object, so the calling terminate () object may know that the thread has been safely stopped.
In cases where there is a danger of deadlocks, SafeThread :: terminate () can take a timeout parameter. If the timeout expires, it calls Thread :: terminate (), thereby killing the thread intrusively. This is the last resource when you have something that you cannot control (for example, a third-party API) or in situations where a dead end does more damage than resource leaks, etc.
I hope this will be useful for your decision and will give you a fairly clear idea of โโmy design options. If not, I can post code snippets to clarify if you want to.
Fabio Ceconello May 16 '10 at 23:51 2010-05-16 23:51
source share