I was going through a legacy code and found the following snippet:
MyClass::~MyClass()
{
EnterCriticalSection(&cs);
//Access Data Members, **NO Global**
I have seen a case with ACE threads, where the thread is running on an ACE_Task_Base object and the object is destroyed from another thread. The destructor acquires a lock and notifies the contained thread, just before waiting on a condition. The thread that is running on the ACE_Task_Base signal signals the condition at exit and lets the destructor complete and the first thread exit:
class PeriodicThread : public ACE_Task_Base
{
public:
PeriodicThread() : exit_( false ), mutex_()
{
}
~PeriodicThread()
{
mutex_.acquire();
exit_ = true;
mutex_.release();
wait(); // wait for running thread to exit
}
int svc()
{
mutex_.acquire();
while ( !exit_ ) {
mutex_.release();
// perform periodic operation
mutex_.acquire();
}
mutex_.release();
}
private:
bool exit_;
ACE_Thread_Mutex mutex_;
};
In this code, the destructor must use thread safety techniques to guarantee that the object is not destroyed before the thread that is running svc() exits.