X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d1bab566475b6573c1c0c982eec395c6d8eef13a..2654f7e423bb773ca52c8b465c6ec9abfa398e45:/src/os2/thread.cpp?ds=sidebyside diff --git a/src/os2/thread.cpp b/src/os2/thread.cpp index eefb6d5f15..738a99a758 100644 --- a/src/os2/thread.cpp +++ b/src/os2/thread.cpp @@ -6,7 +6,7 @@ // Created: 04/22/98 // RCS-ID: $Id$ // Copyright: (c) Stefan Neis (2003) -// +// // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -26,6 +26,7 @@ #include #include "wx/app.h" +#include "wx/apptrait.h" #include "wx/module.h" #include "wx/intl.h" #include "wx/utils.h" @@ -377,7 +378,7 @@ public: TID GetId() const { return m_hThread; } // thread function - static DWORD OS2ThreadStart(ULONG ulParam); + static void OS2ThreadStart(void* pParam); private: // Threads in OS/2 have only an ID, so m_hThread is both it's handle and ID @@ -388,16 +389,20 @@ private: unsigned int m_nPriority; // thread priority in "wx" units }; -ULONG wxThreadInternal::OS2ThreadStart( - ULONG ulParam +void wxThreadInternal::OS2ThreadStart( + void * pParam ) { DWORD dwRet; bool bWasCancelled; - // first of all, check whether we hadn't been cancelled already and don't - // start the user code at all then - wxThread *pThread = (wxThread *)ulParam; + wxThread *pThread = (wxThread *)pParam; + + // first of all, wait for the thread to be started. + pThread->m_critsect.Enter(); + pThread->m_critsect.Leave(); + // Now check whether we hadn't been cancelled already and don't + // start the user code at all in this case. if ( pThread->m_internal->GetState() == STATE_EXITED ) { dwRet = (DWORD)-1; @@ -405,15 +410,21 @@ ULONG wxThreadInternal::OS2ThreadStart( } else // do run thread { + wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL; + unsigned long ulHab; + if (traits) + traits->InitializeGui(ulHab); dwRet = (DWORD)pThread->Entry(); + if (traits) + traits->TerminateGui(ulHab); - // enter m_critsect before changing the thread state - pThread->m_critsect.Enter(); + // enter m_critsect before changing the thread state + pThread->m_critsect.Enter(); - bWasCancelled = pThread->m_internal->GetState() == STATE_CANCELED; + bWasCancelled = pThread->m_internal->GetState() == STATE_CANCELED; - pThread->m_internal->SetState(STATE_EXITED); - pThread->m_critsect.Leave(); + pThread->m_internal->SetState(STATE_EXITED); + pThread->m_critsect.Leave(); } pThread->OnExit(); @@ -425,7 +436,7 @@ ULONG wxThreadInternal::OS2ThreadStart( delete pThread; } //else: the joinable threads handle will be closed when Wait() is done - return dwRet; + return; } void wxThreadInternal::SetPriority( @@ -468,20 +479,20 @@ bool wxThreadInternal::Create( , unsigned int uStackSize ) { - APIRET ulrc; - - ulrc = ::DosCreateThread( &m_hThread - ,(PFNTHREAD)wxThreadInternal::OS2ThreadStart - ,(ULONG)pThread - ,CREATE_SUSPENDED | STACK_SPARSE - ,(ULONG)uStackSize - ); - if(ulrc != 0) + int tid; + + if (!uStackSize) + uStackSize = 131072; + pThread->m_critsect.Enter(); + tid = _beginthread(wxThreadInternal::OS2ThreadStart, + NULL, uStackSize, pThread); + if(tid == -1) { wxLogSysError(_("Can't create thread")); return FALSE; } + m_hThread = tid; if (m_nPriority != WXTHREAD_DEFAULT_PRIORITY) { SetPriority(m_nPriority); @@ -509,7 +520,7 @@ bool wxThreadInternal::Resume() if (ulrc != 0) { - wxLogSysError(_("Can not suspend thread %lu"), m_hThread); + wxLogSysError(_("Can not resume thread %lu"), m_hThread); return FALSE; } @@ -649,6 +660,13 @@ wxThreadError wxThread::Pause() wxThreadError wxThread::Resume() { + if (m_internal->GetState() == STATE_NEW) + { + m_internal->SetState(STATE_RUNNING); + m_critsect.Leave(); + return wxTHREAD_NO_ERROR; + } + wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); return m_internal->Resume() ? wxTHREAD_NO_ERROR : wxTHREAD_MISC_ERROR; @@ -716,7 +734,7 @@ wxThreadError wxThread::Delete(ExitCode *pRc) { // set flag for wxIsWaitingForThread() gs_bWaitingForThread = TRUE; - } + } // ask the thread to terminate if ( shouldCancel ) @@ -726,7 +744,7 @@ wxThreadError wxThread::Delete(ExitCode *pRc) m_internal->Cancel(); } -#if wxUSE_GUI +#if 0 // we can't just wait for the thread to terminate because it might be // calling some GUI functions and so it will never terminate before we // process the Windows messages that result from these functions @@ -743,25 +761,42 @@ wxThreadError wxThread::Delete(ExitCode *pRc) } } - result = ::DosWaitThread(&hThread, DCWW_WAIT); - // FIXME: We ought to have a message processing loop here!! + result = ::DosWaitThread(&hThread, DCWW_NOWAIT); + // FIXME: We ought to have a message processing loop here!! switch ( result ) - { - case ERROR_THREAD_NOT_TERMINATED: - case ERROR_INVALID_THREADID: - // error - wxLogSysError(_("Can not wait for thread termination")); - Kill(); - return wxTHREAD_KILLED; - + { + case ERROR_INTERRUPT: + case ERROR_THREAD_NOT_TERMINATED: + break; + case ERROR_INVALID_THREADID: case NO_ERROR: - // thread we're waiting for terminated + // thread we're waiting for just terminated + // or even does not exist any more. + result = NO_ERROR; break; - default: wxFAIL_MSG(wxT("unexpected result of DosWaitThread")); } + if ( IsMain() ) + { + // event processing - needed if we are the main thread + // to give other threads a chance to do remaining GUI + // processing and terminate cleanly. + wxTheApp->HandleSockets(); + if (wxTheApp->Pending()) + if ( !wxTheApp->DoMessage() ) + { + // WM_QUIT received: kill the thread + Kill(); + + return wxTHREAD_KILLED; + } + else + wxUsleep(10); + } + else + wxUsleep(10); } while ( result != NO_ERROR ); #else // !wxUSE_GUI // simply wait for the thread to terminate @@ -828,7 +863,7 @@ void wxThread::Exit( ) { delete this; - ::DosExit(EXIT_THREAD, ULONG(pStatus)); + _endthread(); wxFAIL_MSG(wxT("Couldn't return from DosExit()!")); } @@ -939,11 +974,13 @@ void wxThreadModule::OnExit() // wake up the main thread if it's in ::GetMessage() void WXDLLEXPORT wxWakeUpMainThread() { +#if 0 if ( !::WinPostQueueMsg(wxTheApp->m_hMq, WM_NULL, 0, 0) ) { // should never happen wxLogLastError(wxT("WinPostMessage(WM_NULL)")); } +#endif } void WXDLLEXPORT wxMutexGuiEnter()