X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/28a4627cfe8711ddc7644585790ae9463267217a..8def743e8fcd51ba3e68cb6b59154d3557e18f79:/src/msw/thread.cpp diff --git a/src/msw/thread.cpp b/src/msw/thread.cpp index df5e9a437f..ac600434e9 100644 --- a/src/msw/thread.cpp +++ b/src/msw/thread.cpp @@ -41,7 +41,19 @@ #define _MT #endif -#ifdef __VISUALC__ +#if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500)) + +#if defined(__BORLANDC__) && !defined(__MT__) +// I can't set -tWM in the IDE (anyone?) so have to do this +#define __MT__ +#endif + +#if defined(__BORLANDC__) && !defined(__MFC_COMPAT__) +// Needed to know about _beginthreadex etc.. +#define __MFC_COMPAT__ +#endif + + #include #endif @@ -99,33 +111,43 @@ static bool gs_waitingForThread = FALSE; class wxMutexInternal { public: - HANDLE p_mutex; + wxMutexInternal() + { + m_mutex = ::CreateMutex(NULL, FALSE, NULL); + if ( !m_mutex ) + { + wxLogSysError(_("Can not create mutex")); + } + } + + ~wxMutexInternal() { if ( m_mutex ) CloseHandle(m_mutex); } + +public: + HANDLE m_mutex; }; wxMutex::wxMutex() { m_internal = new wxMutexInternal; - m_internal->p_mutex = CreateMutex(NULL, FALSE, NULL); - if ( !m_internal->p_mutex ) - { - 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); - CloseHandle(m_internal->p_mutex); + if ( m_locked > 0 ) + { + wxLogDebug(_T("Warning: freeing a locked mutex (%d locks)."), m_locked); + } + + delete m_internal; } wxMutexError wxMutex::Lock() { DWORD ret; - ret = WaitForSingleObject(m_internal->p_mutex, INFINITE); + ret = WaitForSingleObject(m_internal->m_mutex, INFINITE); switch ( ret ) { case WAIT_ABANDONED: @@ -152,7 +174,7 @@ wxMutexError wxMutex::TryLock() { DWORD ret; - ret = WaitForSingleObject(m_internal->p_mutex, 0); + ret = WaitForSingleObject(m_internal->m_mutex, 0); if (ret == WAIT_TIMEOUT || ret == WAIT_ABANDONED) return wxMUTEX_BUSY; @@ -165,7 +187,7 @@ wxMutexError wxMutex::Unlock() if (m_locked > 0) m_locked--; - BOOL ret = ReleaseMutex(m_internal->p_mutex); + BOOL ret = ReleaseMutex(m_internal->m_mutex); if ( ret == 0 ) { wxLogSysError(_("Couldn't release a mutex")); @@ -363,6 +385,12 @@ private: DWORD wxThreadInternal::WinThreadStart(wxThread *thread) { + // first of all, check whether we hadn't been cancelled already + if ( thread->m_internal->GetState() == STATE_EXITED ) + { + return (DWORD)-1; + } + // store the thread object in the TLS if ( !::TlsSetValue(gs_tlsThisThread, thread) ) { @@ -426,11 +454,11 @@ bool wxThreadInternal::Create(wxThread *thread) // for compilers which have it, we should use C RTL function for thread // creation instead of Win32 API one because otherwise we will have memory // leaks if the thread uses C RTL (and most threads do) -#ifdef __VISUALC__ +#if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500)) typedef unsigned (__stdcall *RtlThreadStart)(void *); m_hThread = (HANDLE)_beginthreadex(NULL, 0, - (RtlThreadStart) + (RtlThreadStart) wxThreadInternal::WinThreadStart, thread, CREATE_SUSPENDED, (unsigned int *)&m_tid); @@ -515,6 +543,10 @@ bool wxThread::IsMain() return ::GetCurrentThreadId() == gs_idMainThread; } +#ifdef Yield +#undef Yield +#endif + void wxThread::Yield() { // 0 argument to Sleep() is special and means to just give away the rest of @@ -595,7 +627,7 @@ bool wxThread::SetConcurrency(size_t level) // set it: we can't link to SetProcessAffinityMask() because it doesn't // exist in Win9x, use RT binding instead - typedef BOOL (*SETPROCESSAFFINITYMASK)(HANDLE, DWORD *); + typedef BOOL (*SETPROCESSAFFINITYMASK)(HANDLE, DWORD); // can use static var because we're always in the main thread here static SETPROCESSAFFINITYMASK pfnSetProcessAffinityMask = NULL; @@ -606,7 +638,12 @@ bool wxThread::SetConcurrency(size_t level) if ( hModKernel ) { pfnSetProcessAffinityMask = (SETPROCESSAFFINITYMASK) - ::GetProcAddress(hModKernel, _T("SetProcessAffinityMask")); + ::GetProcAddress(hModKernel, +#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x520) + "SetProcessAffinityMask"); +#else + _T("SetProcessAffinityMask")); +#endif } // we've discovered a MT version of Win9x! @@ -621,7 +658,7 @@ bool wxThread::SetConcurrency(size_t level) return FALSE; } - if ( pfnSetProcessAffinityMask(hProcess, &dwProcMask) == 0 ) + if ( pfnSetProcessAffinityMask(hProcess, dwProcMask) == 0 ) { wxLogLastError(_T("SetProcessAffinityMask")); @@ -714,11 +751,29 @@ wxThreadError wxThread::Delete(ExitCode *pRc) ExitCode rc = 0; // Delete() is always safe to call, so consider all possible states - if ( IsPaused() ) + + // has the thread started to run? + bool shouldResume = FALSE; + + { + wxCriticalSectionLocker lock(m_critsect); + + if ( m_internal->GetState() == STATE_NEW ) + { + // WinThreadStart() will see it and terminate immediately + m_internal->SetState(STATE_EXITED); + + shouldResume = TRUE; + } + } + + // is the thread paused? + if ( shouldResume || IsPaused() ) Resume(); HANDLE hThread = m_internal->GetHandle(); + // does is still run? if ( IsRunning() ) { if ( IsMain() ) @@ -869,7 +924,7 @@ void wxThread::Exit(ExitCode status) delete this; } -#ifdef __VISUALC__ +#if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500)) _endthreadex((unsigned)status); #else // !VC++ ::ExitThread((DWORD)status);