windows: Avoid potential races with canceling threads
The previous code did not synchronize some of the flags, so it was
possible that `cancel()` did not work properly (e.g. no APC queued).
This change uses atomics to set/read the flags, it also avoids using
the global thread lock for synchronization as getting the condvar before
queuing the APC avoids having to sync with `docancel()`. However, to
make sure we don't use a stale and potentially already freed condvar
when the thread is canceled a new lock is added and held until the
condvar has been signaled (using atomics for that member doesn't work as
the ordering rules enforced by atomics can not avoid that the thread in
`cancel()` potentially reads a stale value, or the race between reading
and signaling it).