I think this is a simple question. I am using the Win32 threading API,
and I have one thread that performs a task at regular intervals. I
wanted to be able to cleanly shut that thread down from another thread
without having to wait for the interval to pass. I have found a
cleaner solution using an event + WaitForMultipleObjects, but I have a
question about my original attempt. Originally, I had used a
combination of a boolean "quit flag" + an interruptible call to
SleepEx. I queued a user APC request as a hack, of sorts, to interrupt
the SleepEx call. The implementation was sort of like this:
volatile bool quit_flag = false;
void interval_thread () {
while (!quit_flag) {
if (SleepEx(interval, TRUE) == WAIT_IO_COMPLETION)
continue;
// perform task here
}
}
void stop_thread () {
quit_flag = true;
QueueUserAPC(&noop, interval_thread_handle, 0);
}
Where "noop" was a dummy function that did nothing. I'm not worried
about the APC hack itself, it seemed to do what I want -- cause
SleepEx to return early and examine "quit_flag" asap. My question is
(just out of curiosity), when I set quit_flag to true before
interrupting SleepEx(), am I guaranteed that when SleepEx() is
interrupted, and continues, it will see quit_flag's value as true
(note that quit_flag is declared volatile)? Or is there some kind of
memory barrier or compiler optimization related issue that may prevent
interval_thread() from seeing things happen in that order?
The only thing that could interrupt SleepEx is a stop_thread() call,
so I could just break from the while loop instead of continuing. Also
I've since switched to a much cleaner implementation. Again, it's
mostly just out of curiosity.
Thanks,
Jason


|