It's actually another way around. ResumeThread won't decrement suspend count
below zero. The race condition happens when ResumeThread is called before
SuspendThread. Then you have an extra suspend count. If your logic issues
suspended forever.
"Michael K. O'Neill" <MikeAThon2000@nospam.hotmail.com> wrote in message
"Scoots" <linkingfire@msn.com> wrote in message
news:1186756765.016660.182240@q4g2000prc.googlegroups.com...
Solved. Thanks for looking.
The afxBeginThread I was using wasn't initializing the CWinThread base
of the derived object, and so the local m_hThread was never being
set. By adding a local handle and removing the derivation, I can
SuspendThread(handle) now.
A thread should ordinarily not use SuspendThread() to suspend itself. The
SuspendThread() function is primarily a debugging function, which the
debugger can use to suspend threads that are being debugged (and to resume
them with ResumeThread()). Thus, SuspendThread should usually be used
only
by a debugging thread, to suspend a target thread, and not by the target
thread itself.
This is mentioned in the docs: "This function is primarily designed for
use
by debuggers. It is not intended to be used for thread synchronization.
Calling SuspendThread on a thread that owns a synchronization object, such
as a mutex or critical section, can lead to a deadlock if the calling
thread
tries to obtain a synchronization object owned by a suspended thread. To
avoid this situation, a thread within an application that is not a
debugger
should signal the other thread to suspend itself. The target thread must
be
designed to watch for this signal and respond appropriately." See
http://msdn2.microsoft.com/en-us/library/ms686345.aspx
The reason is related to a possible race condition with the suspend count.
The suspend count is incremented by a call to SuspendThread(), and is
decremented by a call to ResumeThread(). If the suspend count is
non-zero,
then the scheduler will mark the thread as "waiting" (or not ready), and
will not schedule the thread for processing; conversely, when the suspend
count is exactly zero, the thread is marked as "ready" and is given
processing time. The race condition occurs because access to the suspend
count is not synchronized between threads, such that it is possible for
one
thread to decrement the suspend count beyond zero to a value of -1. At
that
value, the thread will never be scheduled for processing.
Naturally, this race condition can't happen if the thread that calls
SuspendThread() is also the thread that's responsible for calling
ResumeThread(), which is precisely what happens in a debugger. However,
the
usage that you have shown, where the worker thread suspends itself and
therefore must rely on some other thread to call ResumeThread, is a race
condition waiting to happen.