replaced ++/-- with InterlockedInc/Decrement for accessing global vars

also cleaned wxConditionInternal code a bit (more)


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8639 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2000-10-26 00:19:13 +00:00
parent bbee61e50e
commit 4d1c1c3c70

View File

@ -211,44 +211,78 @@ class wxConditionInternal
public: public:
wxConditionInternal() wxConditionInternal()
{ {
event = ::CreateEvent( m_hEvent = ::CreateEvent(
NULL, // default secutiry NULL, // default secutiry
FALSE, // not manual reset FALSE, // not manual reset
FALSE, // nonsignaled initially FALSE, // nonsignaled initially
NULL // nameless event NULL // nameless event
); );
if ( !event ) if ( !m_hEvent )
{ {
wxLogSysError(_("Can not create event object.")); wxLogSysError(_("Can not create event object."));
} }
waiters = 0;
// nobody waits for us yet
m_nWaiters = 0;
} }
bool Wait(DWORD timeout) bool Wait(DWORD timeout)
{ {
waiters++; // as m_nWaiters variable is accessed from multiple waiting threads
// (and possibly from the broadcasting thread), we need to change its
// value atomically
::InterlockedIncrement(&m_nWaiters);
// FIXME this should be MsgWaitForMultipleObjects() as well probably // FIXME this should be MsgWaitForMultipleObjects() as we want to keep
DWORD rc = ::WaitForSingleObject(event, timeout); // processing Windows messages while waiting (or don't we?)
DWORD rc = ::WaitForSingleObject(m_hEvent, timeout);
waiters--; ::InterlockedDecrement(&m_nWaiters);
return rc != WAIT_TIMEOUT; return rc != WAIT_TIMEOUT;
} }
void Signal()
{
// set the event to signaled: if a thread is already waiting on it, it
// will be woken up, otherwise the event will remain in the signaled
// state until someone waits on it. In any case, the system will return
// it to a non signalled state afterwards. If multiple threads are
// waiting, only one will be woken up.
if ( !::SetEvent(m_hEvent) )
{
wxLogLastError(wxT("SetEvent"));
}
}
void Broadcast()
{
// this works because all these threads are already waiting and so each
// SetEvent() inside Signal() is really a PulseEvent() because the
// event state is immediately returned to non-signaled
for ( LONG n = 0; n < m_nWaiters; n++ )
{
Signal();
}
}
~wxConditionInternal() ~wxConditionInternal()
{ {
if ( event ) if ( m_hEvent )
{ {
if ( !::CloseHandle(event) ) if ( !::CloseHandle(m_hEvent) )
{ {
wxLogLastError(wxT("CloseHandle(event)")); wxLogLastError(wxT("CloseHandle(event)"));
} }
} }
} }
HANDLE event; private:
int waiters; // the Win32 synchronization object corresponding to this event
HANDLE m_hEvent;
// number of threads waiting for this condition
LONG m_nWaiters;
}; };
wxCondition::wxCondition() wxCondition::wxCondition()
@ -274,26 +308,12 @@ bool wxCondition::Wait(unsigned long sec,
void wxCondition::Signal() void wxCondition::Signal()
{ {
// set the event to signaled: if a thread is already waiting on it, it will m_internal->Signal();
// be woken up, otherwise the event will remain in the signaled state until
// someone waits on it. In any case, the system will return it to a non
// signalled state afterwards. If multiple threads are waiting, only one
// will be woken up.
if ( !::SetEvent(m_internal->event) )
{
wxLogLastError(wxT("SetEvent"));
}
} }
void wxCondition::Broadcast() void wxCondition::Broadcast()
{ {
// this works because all these threads are already waiting and so each m_internal->Broadcast();
// SetEvent() inside Signal() is really a PulseEvent() because the event
// state is immediately returned to non-signaled
for ( int i = 0; i < m_internal->waiters; i++ )
{
Signal();
}
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -1126,7 +1146,7 @@ void WXDLLEXPORT wxMutexGuiLeave()
} }
else else
{ {
// decrement the number of waiters now // decrement the number of threads waiting for GUI access now
wxASSERT_MSG( gs_nWaitingForGui > 0, wxASSERT_MSG( gs_nWaitingForGui > 0,
wxT("calling wxMutexGuiLeave() without entering it first?") ); wxT("calling wxMutexGuiLeave() without entering it first?") );