#define _MT
#endif
-#ifdef __VISUALC__
+#if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500))
#include <process.h>
#endif
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:
{
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;
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"));
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) )
{
// 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);
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
// 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;
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!
return FALSE;
}
- if ( pfnSetProcessAffinityMask(hProcess, &dwProcMask) == 0 )
+ if ( pfnSetProcessAffinityMask(hProcess, dwProcMask) == 0 )
{
wxLogLastError(_T("SetProcessAffinityMask"));
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() )
delete this;
}
-#ifdef __VISUALC__
+#if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500))
_endthreadex((unsigned)status);
#else // !VC++
::ExitThread((DWORD)status);