views:

224

answers:

1

I'm trying to improve the portability of a C++ app by using boost:threads instead of our own wrapper over Win32 threads, and the issue of graceful thread termination (again) rears its ugly head.

On pure win32, I 'interrupt' threads by using QueueUserAPC to throw a "thread_interrupt" exception which causes all RAII objects to cleanup on the way out, as described here. Any 'alertable' OS function can be interrupted in this way, so things like mutex waits, sleeps, serial and socket I/O are all possible interruption points.

However, boost:mutexes etc. aren't "alertable" by QueueUserAPC on win32 - they call things like Sleep(n) rather then SleepEx(n, true))

Boost threads do have an "interrupt" mechanism (which similarly involves throwing an exception) but it seems to have the drawback that ONLY boost::thread calls are interruptable, so a third-party socket library (for example) cannot be interrupted.

What to do? I could modify the boost source locally to make it interruptable, but that feels like a poor choice and I don't think helps the portability. Redesigning the entire app to remove the requirement for graceful thread shutdown is a similarly unappealing route...

+1  A: 

I have an idea for a partial solution for Win32, but I have yet to test it:

My "thread interrupt" method could call both boost::thread.interrupt(), AND QueueUserAPC and The function invoked by QueueUserAPC would just call boost::interruption_point() to allow the boost interrupt to take control.

This should mean that the thread gets interrupted (but "differently") both when it's waiting on a boost synchronization object or an 'alertable' native windows one.

Roddy