- we were canceling tasks that hadn't been canceled, because the canceled flag was left set to true and the next task assigned to the context then became canceled as soon as it yielded
- we were resumeing blocked tasks before they should have resumed, because their blocking_promises list wasn't cleared and they were unblocking because the erroneous promises were fulfilled
As a debugging aid, we also record the cancellation reason whenever a task is canceled, and include that in the canceled_exception (this is only enabled in debug builds)
Something about the stacks created by boost::context prevents global structured exception handlers
from being called. This allows the user to register a handler which will be called when there
is an unhandled structured exception in async task.
In certain cases when usleep is passed a small value, there is
a race condition that would cause the process to hang and then
when an attempt to quit the thread was made new contexts would
be allocated rapidly filling all available memory.