X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3b9e3455225b670d30ee0fb67f8821ada9640f6d..8c3288a7b682794e4c4a60f2b8487627d0f7c1aa:/src/os2/thread.cpp diff --git a/src/os2/thread.cpp b/src/os2/thread.cpp index 7b4a4643c8..db6ba06510 100644 --- a/src/os2/thread.cpp +++ b/src/os2/thread.cpp @@ -21,6 +21,9 @@ #include #include "wx/module.h" +#include "wx/intl.h" +#include "wx/utils.h" +#include "wx/log.h" #include "wx/thread.h" #define INCL_DOSSEMAPHORES @@ -53,21 +56,21 @@ wxMutex* p_wxMainMutex; wxThread* m_pThread; // pointer to the wxWindows thread object // if it's FALSE, some secondary thread is holding the GUI lock -static bool s_bGuiOwnedByMainThread = TRUE; +static bool gs_bGuiOwnedByMainThread = TRUE; // critical section which controls access to all GUI functions: any secondary // thread (i.e. except the main one) must enter this crit section before doing // any GUI calls -static wxCriticalSection *s_pCritsectGui = NULL; +static wxCriticalSection *gs_pCritsectGui = NULL; // critical section which protects s_nWaitingForGui variable -static wxCriticalSection *s_pCritsectWaitingForGui = NULL; +static wxCriticalSection *gs_pCritsectWaitingForGui = NULL; // number of threads waiting for GUI in wxMutexGuiEnter() -static size_t s_nWaitingForGui = 0; +static size_t gs_nWaitingForGui = 0; // are we waiting for a thread termination? -static bool s_bWaitingForThread = FALSE; +static bool gs_bWaitingForThread = FALSE; // ============================================================================ // OS/2 implementation of thread classes @@ -82,7 +85,9 @@ public: HMTX m_vMutex; }; -wxMutex::wxMutex() +wxMutex::wxMutex( + wxMutexType eMutexType +) { APIRET ulrc; @@ -92,13 +97,10 @@ wxMutex::wxMutex() { wxLogSysError(_("Can not create mutex.")); } - m_locked = 0; } wxMutex::~wxMutex() { - if (m_locked > 0) - wxLogDebug(wxT("Warning: freeing a locked mutex (%d locks)."), m_locked); ::DosCloseMutexSem(m_internal->m_vMutex); m_internal->m_vMutex = NULL; } @@ -128,7 +130,6 @@ wxMutexError wxMutex::Lock() default: wxFAIL_MSG(wxT("impossible return value in wxMutex::Lock")); } - m_locked++; return wxMUTEX_NO_ERROR; } @@ -140,7 +141,6 @@ wxMutexError wxMutex::TryLock() if (ulrc == ERROR_TIMEOUT || ulrc == ERROR_TOO_MANY_SEM_REQUESTS) return wxMUTEX_BUSY; - m_locked++; return wxMUTEX_NO_ERROR; } @@ -148,9 +148,6 @@ wxMutexError wxMutex::Unlock() { APIRET ulrc; - if (m_locked > 0) - m_locked--; - ulrc = ::DosReleaseMutexSem(m_internal->m_vMutex); if (ulrc != 0) { @@ -167,7 +164,7 @@ wxMutexError wxMutex::Unlock() class wxConditionInternal { public: - inline wxConditionInternal () + inline wxConditionInternal (wxMutex& rMutex) : m_vMutex(rMutex) { ::DosCreateEventSem(NULL, &m_vEvent, DC_SEM_SHARED, FALSE); if (!m_vEvent) @@ -177,7 +174,7 @@ public: m_nWaiters = 0; } - inline bool Wait( + inline APIRET Wait( unsigned long ulTimeout ) { @@ -186,7 +183,7 @@ public: m_nWaiters++; ulrc = ::DosWaitEventSem(m_vEvent, ulTimeout); m_nWaiters--; - return (ulrc != ERROR_TIMEOUT); + return (ulrc); } inline ~wxConditionInternal () @@ -205,14 +202,15 @@ public: HEV m_vEvent; int m_nWaiters; + wxMutex& m_vMutex; }; -wxCondition::wxCondition() +wxCondition::wxCondition(wxMutex& rMutex) { APIRET ulrc; ULONG ulCount; - m_internal = new wxConditionInternal; + m_internal = new wxConditionInternal(rMutex); ulrc = ::DosCreateEventSem(NULL, &m_internal->m_vEvent, 0L, FALSE); if (ulrc != 0) { @@ -230,34 +228,80 @@ wxCondition::~wxCondition() m_internal = NULL; } -void wxCondition::Wait() +wxCondError wxCondition::Wait() { - (void)m_internal->Wait(SEM_INFINITE_WAIT); + APIRET rc = m_internal->Wait(SEM_INDEFINITE_WAIT); + + switch(rc) + { + case NO_ERROR: + return wxCOND_NO_ERROR; + case ERROR_INVALID_HANDLE: + return wxCOND_INVALID; + case ERROR_TIMEOUT: + return wxCOND_TIMEOUT; + default: + return wxCOND_MISC_ERROR; + } } -bool wxCondition::Wait( - unsigned long lSec -, unsigned long lNsec) +wxCondError wxCondition::WaitTimeout( + unsigned long lMilliSec +) { - return m_internal->Wait(lSec*1000 + lNsec/1000000); + APIRET rc = m_internal->Wait(lMilliSec); + + switch(rc) + { + case NO_ERROR: + return wxCOND_NO_ERROR; + case ERROR_INVALID_HANDLE: + return wxCOND_INVALID; + case ERROR_TIMEOUT: + return wxCOND_TIMEOUT; + default: + return wxCOND_MISC_ERROR; + } } -void wxCondition::Signal() +wxCondError wxCondition::Signal() { - ::DosPostEventSem(m_internal->m_vEvent); + APIRET rc = ::DosPostEventSem(m_internal->m_vEvent); + + switch(rc) + { + case NO_ERROR: + return wxCOND_NO_ERROR; + case ERROR_INVALID_HANDLE: + return wxCOND_INVALID; + default: + return wxCOND_MISC_ERROR; + } } -void wxCondition::Broadcast() +wxCondError wxCondition::Broadcast() { int i; + APIRET rc = NO_ERROR; for (i = 0; i < m_internal->m_nWaiters; i++) { - if (::DosPostEventSem(m_internal->m_vEvent) != 0) + if ((rc = ::DosPostEventSem(m_internal->m_vEvent)) != NO_ERROR) { wxLogSysError(_("Couldn't change the state of event object.")); + break; } } + + switch(rc) + { + case NO_ERROR: + return wxCOND_NO_ERROR; + case ERROR_INVALID_HANDLE: + return wxCOND_INVALID; + default: + return wxCOND_MISC_ERROR; + } } // ---------------------------------------------------------------------------- @@ -314,7 +358,9 @@ public: } // create a new (suspended) thread (for the given thread object) - bool Create(wxThread* pThread); + bool Create( wxThread* pThread + ,unsigned int uStackSize + ); // suspend/resume/terminate bool Suspend(); @@ -356,10 +402,10 @@ ULONG wxThreadInternal::OS2ThreadStart( // enter m_critsect before changing the thread state pThread->m_critsect.Enter(); - bool bWasCancelled = thread->m_internal->GetState() == STATE_CANCELED; + bool bWasCancelled = pThread->m_internal->GetState() == STATE_CANCELED; pThread->m_internal->SetState(STATE_EXITED); - thread->m_critsect.Leave(); + pThread->m_critsect.Leave(); pThread->OnExit(); @@ -368,7 +414,7 @@ ULONG wxThreadInternal::OS2ThreadStart( if (pThread->IsDetached() && !bWasCancelled) { // auto delete - delete thread; + delete pThread; } //else: the joinable threads handle will be closed when Wait() is done return dwRet; @@ -380,6 +426,7 @@ void wxThreadInternal::SetPriority( { // translate wxWindows priority to the PM one ULONG ulOS2_Priority; + ULONG ulrc; m_nPriority = nPriority; @@ -411,6 +458,7 @@ void wxThreadInternal::SetPriority( bool wxThreadInternal::Create( wxThread* pThread +, unsigned int uStackSize ) { APIRET ulrc; @@ -419,7 +467,7 @@ bool wxThreadInternal::Create( ,(PFNTHREAD)wxThreadInternal::OS2ThreadStart ,(ULONG)pThread ,CREATE_SUSPENDED | STACK_SPARSE - ,8192L + ,(ULONG)uStackSize ); if(ulrc != 0) { @@ -515,9 +563,11 @@ wxThread::~wxThread() // create/start thread // ------------------- -wxThreadError wxThread::Create() +wxThreadError wxThread::Create( + unsigned int uStackSize +) { - if ( !m_internal->Create(this) ) + if ( !m_internal->Create(this, uStackSize) ) return wxTHREAD_NO_RESOURCE; return wxTHREAD_NO_ERROR; @@ -582,7 +632,7 @@ wxThreadError wxThread::Delete(ExitCode *pRc) if (IsMain()) { // set flag for wxIsWaitingForThread() - gs_waitingForThread = TRUE; + gs_bWaitingForThread = TRUE; #if wxUSE_GUI wxBeginBusyCursor(); @@ -611,7 +661,7 @@ wxThreadError wxThread::Delete(ExitCode *pRc) if ( IsMain() ) { - gs_waitingForThread = FALSE; + gs_bWaitingForThread = FALSE; #if wxUSE_GUI wxEndBusyCursor(); @@ -626,9 +676,6 @@ wxThreadError wxThread::Delete(ExitCode *pRc) delete this; } - wxASSERT_MSG( (DWORD)rc != STILL_ACTIVE, - wxT("thread must be already terminated.") ); - if ( pRc ) *pRc = rc; @@ -729,10 +776,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule) bool wxThreadModule::OnInit() { - s_pCritsectWaitingForGui = new wxCriticalSection(); + gs_pCritsectWaitingForGui = new wxCriticalSection(); - s_pCritsectGui = new wxCriticalSection(); - s_pCritsectGui->Enter(); + gs_pCritsectGui = new wxCriticalSection(); + gs_pCritsectGui->Enter(); PTIB ptib; PPIB ppib; @@ -745,14 +792,18 @@ bool wxThreadModule::OnInit() void wxThreadModule::OnExit() { - if (s_pCritsectGui) + if (gs_pCritsectGui) { - s_pCritsectGui->Leave(); - delete s_pCritsectGui; - s_pCritsectGui = NULL; + gs_pCritsectGui->Leave(); +#if (!(defined(__VISAGECPP__) && (__IBMCPP__ < 400 || __IBMC__ < 400 ))) + delete gs_pCritsectGui; +#endif + gs_pCritsectGui = NULL; } - wxDELETE(s_pCritsectWaitingForGui); +#if (!(defined(__VISAGECPP__) && (__IBMCPP__ < 400 || __IBMC__ < 400 ))) + wxDELETE(gs_pCritsectWaitingForGui); +#endif } // ---------------------------------------------------------------------------- @@ -766,24 +817,24 @@ void WXDLLEXPORT wxWakeUpMainThread() void WXDLLEXPORT wxMutexGuiLeave() { - wxCriticalSectionLocker enter(*s_pCritsectWaitingForGui); + wxCriticalSectionLocker enter(*gs_pCritsectWaitingForGui); if ( wxThread::IsMain() ) { - s_bGuiOwnedByMainThread = FALSE; + gs_bGuiOwnedByMainThread = FALSE; } else { // decrement the number of waiters now - wxASSERT_MSG( s_nWaitingForGui > 0, + wxASSERT_MSG(gs_nWaitingForGui > 0, wxT("calling wxMutexGuiLeave() without entering it first?") ); - s_nWaitingForGui--; + gs_nWaitingForGui--; wxWakeUpMainThread(); } - s_pCritsectGui->Leave(); + gs_pCritsectGui->Leave(); } void WXDLLEXPORT wxMutexGuiLeaveOrEnter() @@ -791,17 +842,17 @@ void WXDLLEXPORT wxMutexGuiLeaveOrEnter() wxASSERT_MSG( wxThread::IsMain(), wxT("only main thread may call wxMutexGuiLeaveOrEnter()!") ); - wxCriticalSectionLocker enter(*s_pCritsectWaitingForGui); + wxCriticalSectionLocker enter(*gs_pCritsectWaitingForGui); - if ( s_nWaitingForGui == 0 ) + if (gs_nWaitingForGui == 0) { // no threads are waiting for GUI - so we may acquire the lock without // any danger (but only if we don't already have it) if (!wxGuiOwnedByMainThread()) { - s_pCritsectGui->Enter(); + gs_pCritsectGui->Enter(); - s_bGuiOwnedByMainThread = TRUE; + gs_bGuiOwnedByMainThread = TRUE; } //else: already have it, nothing to do } @@ -818,12 +869,12 @@ void WXDLLEXPORT wxMutexGuiLeaveOrEnter() bool WXDLLEXPORT wxGuiOwnedByMainThread() { - return s_bGuiOwnedByMainThread; + return gs_bGuiOwnedByMainThread; } bool WXDLLEXPORT wxIsWaitingForThread() { - return s_bWaitingForThread; + return gs_bWaitingForThread; } #endif