I
Ian Collins
Let's suppose my company has an engine which executes SQL from backing
federated data stores, including relational databases of many flavors,
flat files, etc. Let's further suppose that the user wants a "cancel"
button. This should stop the engine processing so that the CPU,
memory, disk, network, and other hardware resources are available to
run another SQL which the user may type in immediately following a
cancel. How would you do this? Or is this one of those rare times
cancel is a good idea?
[slight delay in responding due to a rather large earthquake!]
Cancellation has to be designed in up front. Any form of asynchronous
cancellation is fraught with problems unless the design is async-cancel
safe. It's akin to design exception safe code, only harder. Some run
time environments will clean up, others will not. Nothing is guaranteed
by the standard.
If possible, your loop should include cancellation points so it can
terminate cleanly. Better still use some form of explicit termination
of loops ( while (keep_going) {..} ).
I was thinking about it more, and thought of another couple of angles.
You could wrap the standard library to provide cancellation points
(eww).
Or test for cancellation if your implementation supports it (POSIX
pthread_testcancel() for example).
Alternatively, thread cancellation without timed waits or wrapping the
std might be more maintainable if you keep the number of effective
cancellation points to a bare minimum. Specifically, you don't
sprinkle "if (stopped()) throw stop_exception();" everywhere, and
instead keep the number of effective cancellation points to a very
small number. However, it just seems to be another way to sacrifice
responsiveness (larger blocks of uninterruptable work, like timed
waits) for better maintainability (like always-timed waits).
Everything is software is a compromise! You have to trade
responsiveness with the complexity of being async-cancel safe.