Be sure your allocated memory is owned
Be sure every allocated memory is owned by a smart pointer, either STL's auto_ptr or Boost's scoped_ptr, or even shared_ptr (which can be shared, copied and moved).
This way, RAII will protect you from any memory leak.
Read Interrupt Politely, an article from Herb Sutter explaining miscellaneous ways to interrupt a thread.
Today wth Boost.Thread 1.37, You can ask a thread to terminate by throwing an exception. In Boost, it's the boost::thread_interrupted exception, which will throw an exception from any interruption point.
Thus, you do not need to handle some kind of message loop, or verify some global/shared data. The main thread asks the worker thread to stop through an exception, and as soon as the worker thread reaches an interruption point, the exception is thrown. The RAII mecanism described earlier will make sure all your allocated data will be freed correctly.
Let's say you have some pseudo code that will be called in a thread. It could be something like a function that will perhaps allocated memory, and another that will do a lot of computation inside a loop:
Object * allocateSomeObject()
{
Object * o = NULL ;
if(/*something*/)
{
// Etc.
o = new Object() ;
// Etc.
}
return o ; // o can be NULL
}
void doSomethingLengthy()
{
for(int i = 0; i < 1000; ++i)
{
// Etc.
for(int j = 0; j < 1000; ++j)
{
// Etc.
// transfert of ownership
Object * o = allocateSomeObject() ;
// Etc.
delete o ;
}
// Etc.
}
}
The code above is not safe and will leak not matter the interruption mode if steps are not taken to be sure that at all moments the memory will be owned by a C++ object (usually, a smart pointer).
It could be modified this way to have the code be both interruptible, and memory safe:
boost::shared_ptr<Object> allocateSomeObject()
{
boost::shared_ptr<Object> o ;
if(/*something*/)
{
// Etc.
boost::this_thread::interruption_point() ;
// Etc.
o = new Object() ;
// Etc.
boost::this_thread::interruption_point() ;
// Etc.
}
return o ; // o can be "NULL"
}
void doSomethingLengthy()
{
for(int i = 0; i < 1000; ++i)
{
// Etc.
for(int j = 0; j < 1000; ++j)
{
// Etc.
// transfert of ownership
boost::shared_ptr<Object> o = allocateSomeObject() ;
// Etc.
boost::this_thread::interruption_point() ;
// Etc.
}
// Etc.
boost::this_thread::interruption_point() ;
// Etc.
}
}
void mainThread(boost::thread & worker_thread)
{
// etc.
if(/* some condition */)
{
worker_thread.interrupt() ;
}
}
Do not use Boost?
If you do not use Boost, then you can simulate this. Have some thread storage boolean-like variable set to "true" if the thread should be interrupted. Add functions checking this variable, and then throw a specific exception if true. Have the "root" of your thread catch this exception to have it end correctly.
Disclaimer
I don't have access to Boost 1.37 right now, so I'm unable to test the previous code, but the idea is there. I will test this as soon as possible, and eventually post a more complete/correct/compilable code.