break thread/mutex implementation stuff out of RageThreads
(not used yet)
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
#ifndef THREADS_H
|
||||
#define THREADS_H
|
||||
|
||||
/* This is the low-level implementation; you probably want RageThreads. */
|
||||
class RageMutex;
|
||||
|
||||
|
||||
class ThreadImpl
|
||||
{
|
||||
#if defined(PID_BASED_THREADS)
|
||||
/* Keep a list of child PIDs, so we can send them SIGKILL. This has an
|
||||
* added bonus: if this is corrupted, we'll just send signals and they'll
|
||||
* fail; we won't blow up (unless we're root). */
|
||||
// int pid;
|
||||
#endif
|
||||
|
||||
#if defined(DARWIN)
|
||||
// thread_act_t ThreadHandle;
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual ~ThreadImpl() { }
|
||||
virtual void Halt( bool Kill ) = 0;
|
||||
virtual void Resume() = 0;
|
||||
|
||||
/* Get the identifier for this thread. The actual meaning of this is implementation-
|
||||
* defined, except that each thread has exactly one ID and each ID corresponds to
|
||||
* one thread. (This means that Win32 thread handles are not acceptable as ThreadIds.) */
|
||||
virtual uint64_t GetThreadId() const = 0;
|
||||
|
||||
virtual uint64_t GetCrashHandle() const { return 0; }
|
||||
|
||||
virtual int Wait() = 0;
|
||||
};
|
||||
|
||||
class MutexImpl
|
||||
{
|
||||
public:
|
||||
RageMutex *m_Parent;
|
||||
|
||||
MutexImpl( RageMutex *pParent ) { m_Parent = pParent; }
|
||||
virtual ~MutexImpl() { }
|
||||
|
||||
/* Lock the mutex. If mutex timeouts are implemented, and the mutex times out,
|
||||
* return false and do not lock the mutex. No other failure return is allowed;
|
||||
* all other errors should fail with an assertion. */
|
||||
virtual bool Lock() = 0;
|
||||
|
||||
/* Unlock the mutex. This must only be called when the mutex is locked; implementations
|
||||
* may fail with an assertion if the mutex is not locked. */
|
||||
virtual void Unlock() = 0;
|
||||
|
||||
/* Return the thread ID of the thread that has this mutex locked. If no thread
|
||||
* holds the mutex, return GetInvalidThreadId. */
|
||||
virtual uint64_t GetLockedByThreadId() const = 0;
|
||||
};
|
||||
|
||||
/* These functions must be implemented by the thread implementation. */
|
||||
ThreadImpl *MakeThread( int (*fn)(void *), void *data );
|
||||
ThreadImpl *MakeThisThread();
|
||||
MutexImpl *MakeMutex( RageMutex *pParent );
|
||||
uint64_t GetThisThreadId();
|
||||
|
||||
/* Since ThreadId is implementation-defined, we can't define a universal invalid
|
||||
* value. Return the invalid value for this implementation. */
|
||||
uint64_t GetInvalidThreadId();
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* (c) 2001-2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, and/or sell copies of the Software, and to permit persons to
|
||||
* whom the Software is furnished to do so, provided that the above
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
||||
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
||||
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
@@ -0,0 +1,240 @@
|
||||
#include "global.h"
|
||||
#include "Threads_Pthreads.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
#if defined(LINUX)
|
||||
#define PID_BASED_THREADS
|
||||
#include "archutils/Unix/LinuxThreadHelpers.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PTHREAD_MUTEX_TIMEDLOCK) && defined(CRASH_HANDLER)
|
||||
#include "archutils/Unix/Backtrace.h"
|
||||
#include "archutils/Unix/CrashHandler.h"
|
||||
#endif
|
||||
|
||||
#if defined(DARWIN)
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/thread_act.h>
|
||||
#endif
|
||||
|
||||
void ThreadImpl_Pthreads::Halt( bool Kill )
|
||||
{
|
||||
#if defined(PID_BASED_THREADS)
|
||||
/*
|
||||
* Send a SIGSTOP to the thread. If we send a SIGKILL, pthreads will
|
||||
* "helpfully" propagate it to the other threads, and we'll get killed, too.
|
||||
*
|
||||
* This isn't ideal, since it can cause the process to background as far as
|
||||
* the shell is concerned, so the shell prompt can display before the crash
|
||||
* handler actually displays a message.
|
||||
*/
|
||||
SuspendThread( pid );
|
||||
#elif defined(DARWIN)
|
||||
thread_suspend( MachThreadHandle );
|
||||
#endif
|
||||
}
|
||||
|
||||
void ThreadImpl_Pthreads::Resume()
|
||||
{
|
||||
#if defined(PID_BASED_THREADS)
|
||||
/* Send a SIGCONT to the thread. */
|
||||
ResumeThread( pid );
|
||||
#elif defined(DARWIN)
|
||||
thread_resume( MachThreadHandle );
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t ThreadImpl_Pthreads::GetThreadId() const
|
||||
{
|
||||
#if defined(PID_BASED_THREADS)
|
||||
return (uint64_t) pid;
|
||||
#elif defined(DARWIN)
|
||||
return MachThreadHandle;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ThreadImpl_Pthreads::Wait()
|
||||
{
|
||||
void *val;
|
||||
int ret = pthread_join( thread, &val );
|
||||
if( ret )
|
||||
RageException::Throw( "pthread_join: %s", strerror(ret) );
|
||||
|
||||
return (int) val;
|
||||
}
|
||||
|
||||
static ThreadImpl *MakeThisThread()
|
||||
{
|
||||
ThreadImpl_Pthreads *thread = new ThreadImpl_Pthreads;
|
||||
|
||||
thread->thread = pthread_self();
|
||||
|
||||
#if defined(PID_BASED_THREADS)
|
||||
thread->pid = GetCurrentThreadId(); /* in LinuxThreadHelpers.cpp */
|
||||
#endif
|
||||
|
||||
#if defined(DARWIN)
|
||||
MachThreadHandle = mach_thread_self();
|
||||
#endif
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
static void *StartThread( void *pData )
|
||||
{
|
||||
ThreadImpl_Pthreads *pThis = (ThreadImpl_Pthreads *) pData;
|
||||
|
||||
#if defined(PID_BASED_THREADS)
|
||||
pThis->pid = GetCurrentThreadId(); /* in LinuxThreadHelpers.cpp */
|
||||
#endif
|
||||
|
||||
#if defined(DARWIN)
|
||||
MachThreadHandle = mach_thread_self();
|
||||
#endif
|
||||
|
||||
return (void *) pThis->m_pFunc( pThis->m_pData );
|
||||
}
|
||||
|
||||
ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData )
|
||||
{
|
||||
ThreadImpl_Win32 *thread = new ThreadImpl_Pthreads;
|
||||
thread->m_pFunc = pFunc;
|
||||
thread->m_pData = pData;
|
||||
|
||||
int ret = pthread_create( &thread->thread, NULL, StartThread, thread );
|
||||
if( ret )
|
||||
RageException::Throw( "pthread_create: %s", strerror(ret) );
|
||||
|
||||
/* XXX: don't return until StartThread sets pid, etc */
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
MutexImpl_Pthreads::MutexImpl_Pthreads( RageMutex *pParent ):
|
||||
MutexImpl( pParent )
|
||||
{
|
||||
pthread_mutex_init( &mutex, NULL );
|
||||
LockedBy = GetInvalidThreadId();
|
||||
LockCnt = 0;
|
||||
}
|
||||
|
||||
MutexImpl_Pthreads::~MutexImpl_Pthreads()
|
||||
{
|
||||
int ret = pthread_mutex_destroy( &mutex ) == -1;
|
||||
if( ret )
|
||||
RageException::Throw( "Error deleting mutex: %s", strerror(ret) );
|
||||
}
|
||||
|
||||
|
||||
bool MutexImpl_Pthreads::Lock()
|
||||
{
|
||||
if( LockedBy == GetCurrentThreadId() )
|
||||
{
|
||||
++LockCnt;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(HAVE_PTHREAD_MUTEX_TIMEDLOCK) && defined(CRASH_HANDLER)
|
||||
int len = 10; /* seconds */
|
||||
int tries = 2;
|
||||
|
||||
while( tries-- )
|
||||
{
|
||||
/* Wait for ten seconds. If it takes longer than that, we're probably deadlocked. */
|
||||
timeval tv;
|
||||
gettimeofday( &tv, NULL );
|
||||
|
||||
timespec ts;
|
||||
ts.tv_sec = tv.tv_sec + len;
|
||||
ts.tv_nsec = tv.tv_usec * 1000;
|
||||
int ret = pthread_mutex_timedlock( &mutex, &ts );
|
||||
switch( ret )
|
||||
{
|
||||
case 0:
|
||||
LockedBy = GetCurrentThreadId();
|
||||
return true;
|
||||
|
||||
case ETIMEDOUT:
|
||||
/* Timed out. Probably deadlocked. Try again one more time, with a smaller
|
||||
* timeout, just in case we're debugging and happened to stop while waiting
|
||||
* on the mutex. */
|
||||
len = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
RageException::Throw( "pthread_mutex_timedlock: %s", strerror(ret) );
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
#else
|
||||
int ret = pthread_mutex_lock( &mutex );
|
||||
if( ret )
|
||||
RageException::Throw( "pthread_mutex_lock failed: %s", strerror(ret) );
|
||||
LockedBy = GetCurrentThreadId();
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void MutexImpl_Pthreads::Unlock()
|
||||
{
|
||||
if( LockCnt )
|
||||
{
|
||||
--LockCnt;
|
||||
return;
|
||||
}
|
||||
|
||||
LockedBy = GetInvalidThreadId();
|
||||
pthread_mutex_unlock( &mutex );
|
||||
}
|
||||
|
||||
uint64_t MutexImpl_Pthreads::GetLockedByThreadId() const
|
||||
{
|
||||
return LockedBy;
|
||||
}
|
||||
|
||||
uint64_t GetThisThreadId()
|
||||
{
|
||||
#if defined(PID_BASED_THREADS)
|
||||
return GetCurrentThreadId();
|
||||
#elif defined(DARWIN)
|
||||
return (int) mach_thread_self();
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t GetInvalidThreadId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
MutexImpl *MakeMutex( RageMutex *pParent )
|
||||
{
|
||||
return new MutexImpl_Pthreads( pParent );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (c) 2001-2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, and/or sell copies of the Software, and to permit persons to
|
||||
* whom the Software is furnished to do so, provided that the above
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
||||
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
||||
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
@@ -0,0 +1,74 @@
|
||||
#ifndef THREADS_WIN32_H
|
||||
#define THREADS_WIN32_H
|
||||
|
||||
#include "Threads.h"
|
||||
|
||||
class ThreadImpl_Pthreads: public ThreadImpl
|
||||
{
|
||||
public:
|
||||
// HANDLE ThreadHandle;
|
||||
// DWORD ThreadId;
|
||||
|
||||
pthread_t thread;
|
||||
|
||||
#if defined(PID_BASED_THREADS)
|
||||
/* Keep a list of child PIDs, so we can send them SIGKILL. This has an
|
||||
* added bonus: if this is corrupted, we'll just send signals and they'll
|
||||
* fail; we won't blow up (unless we're root). */
|
||||
int pid;
|
||||
#endif
|
||||
|
||||
#if defined(DARWIN)
|
||||
thread_act_t MachThreadHandle;
|
||||
#endif
|
||||
|
||||
int (*m_pFunc)( void *pData );
|
||||
void *m_pData;
|
||||
|
||||
void Halt( bool Kill );
|
||||
void Resume();
|
||||
uint64_t GetThreadId() const;
|
||||
int Wait();
|
||||
};
|
||||
|
||||
struct MutexImpl_Pthreads: public MutexImpl
|
||||
{
|
||||
uint64_t LockedBy;
|
||||
volatile int LockCnt;
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
MutexImpl_Pthreads( RageMutex *parent );
|
||||
~MutexImpl_Pthreads();
|
||||
|
||||
bool Lock();
|
||||
void Unlock();
|
||||
uint64_t GetLockedByThreadId() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* (c) 2001-2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, and/or sell copies of the Software, and to permit persons to
|
||||
* whom the Software is furnished to do so, provided that the above
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
||||
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
||||
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
@@ -0,0 +1,201 @@
|
||||
#include "global.h"
|
||||
#include "Threads_Win32.h"
|
||||
#include "RageUtil.h"
|
||||
#include "RageThreads.h"
|
||||
|
||||
void ThreadImpl_Win32::Halt( bool Kill )
|
||||
{
|
||||
#ifndef _XBOX
|
||||
if( Kill )
|
||||
TerminateThread( ThreadHandle, 0 );
|
||||
else
|
||||
#endif
|
||||
SuspendThread( ThreadHandle );
|
||||
}
|
||||
|
||||
void ThreadImpl_Win32::Resume()
|
||||
{
|
||||
ResumeThread( ThreadHandle );
|
||||
}
|
||||
|
||||
uint64_t ThreadImpl_Win32::GetThreadId() const
|
||||
{
|
||||
return (uint64_t) ThreadId;
|
||||
}
|
||||
|
||||
uint64_t ThreadImpl_Win32::GetCrashHandle() const
|
||||
{
|
||||
return (uint64_t) ThreadHandle;
|
||||
}
|
||||
|
||||
int ThreadImpl_Win32::Wait()
|
||||
{
|
||||
WaitForSingleObject( ThreadHandle, INFINITE );
|
||||
|
||||
DWORD ret;
|
||||
GetExitCodeThread( ThreadHandle, &ret );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD WINAPI StartThread( LPVOID pData )
|
||||
{
|
||||
ThreadImpl_Win32 *pThis = (ThreadImpl_Win32 *) pData;
|
||||
|
||||
return (DWORD)pThis->m_pFunc( pThis->m_pData );
|
||||
}
|
||||
|
||||
ThreadImpl *MakeThisThread()
|
||||
{
|
||||
ThreadImpl_Win32 *thread = new ThreadImpl_Win32;
|
||||
|
||||
const HANDLE CurProc = GetCurrentProcess();
|
||||
int ret = DuplicateHandle( CurProc, GetCurrentThread(), CurProc,
|
||||
&thread->ThreadHandle, 0, false, DUPLICATE_SAME_ACCESS );
|
||||
|
||||
if( !ret )
|
||||
{
|
||||
// LOG->Warn( werr_ssprintf( GetLastError(), "DuplicateHandle(%p, %p) failed",
|
||||
// CurProc, GetCurrentThread() ) );
|
||||
|
||||
thread->ThreadHandle = NULL;
|
||||
}
|
||||
|
||||
thread->ThreadId = GetCurrentThreadId();
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData )
|
||||
{
|
||||
ThreadImpl_Win32 *thread = new ThreadImpl_Win32;
|
||||
thread->m_pFunc = pFunc;
|
||||
thread->m_pData = pData;
|
||||
|
||||
/* XXX: does ThreadHandle need to be dup'd? */
|
||||
thread->ThreadHandle = CreateThread( NULL, 0, &StartThread, thread, 0, &thread->ThreadId );
|
||||
|
||||
ASSERT_M( thread->ThreadHandle, ssprintf("%s", werr_ssprintf(GetLastError(), "CreateThread")) );
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
|
||||
|
||||
MutexImpl_Win32::MutexImpl_Win32( RageMutex *pParent ):
|
||||
MutexImpl( pParent )
|
||||
{
|
||||
mutex = CreateMutex( NULL, false, NULL );
|
||||
ASSERT_M( mutex != NULL, werr_ssprintf(GetLastError(), "CreateMutex") );
|
||||
LockedBy = GetInvalidThreadId();
|
||||
LockCnt = 0;
|
||||
}
|
||||
|
||||
MutexImpl_Win32::~MutexImpl_Win32()
|
||||
{
|
||||
CloseHandle( mutex );
|
||||
}
|
||||
|
||||
bool MutexImpl_Win32::Lock()
|
||||
{
|
||||
if( LockedBy == GetCurrentThreadId() )
|
||||
{
|
||||
++LockCnt;
|
||||
return true;
|
||||
}
|
||||
|
||||
int len = 15000;
|
||||
int tries = 2;
|
||||
|
||||
while( tries-- )
|
||||
{
|
||||
/* Wait for fifteen seconds. If it takes longer than that, we're probably deadlocked. */
|
||||
DWORD ret = WaitForSingleObject( mutex, len );
|
||||
|
||||
switch( ret )
|
||||
{
|
||||
case WAIT_ABANDONED:
|
||||
/* The docs aren't particular about what this does, but it should never happen. */
|
||||
ASSERT( 0 );
|
||||
break;
|
||||
|
||||
case WAIT_OBJECT_0:
|
||||
LockedBy = GetCurrentThreadId();
|
||||
return true;
|
||||
|
||||
case WAIT_TIMEOUT:
|
||||
/* Timed out. Probably deadlocked. Try again one more time, with a smaller
|
||||
* timeout, just in case we're debugging and happened to stop while waiting
|
||||
* on the mutex. */
|
||||
len = 1000;
|
||||
break;
|
||||
|
||||
case WAIT_FAILED:
|
||||
FAIL_M( werr_ssprintf(GetLastError(), "WaitForSingleObject(%s)", this->m_Parent->GetName().c_str()) );
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MutexImpl_Win32::Unlock()
|
||||
{
|
||||
if( LockCnt )
|
||||
{
|
||||
--LockCnt;
|
||||
return;
|
||||
}
|
||||
|
||||
LockedBy = GetInvalidThreadId();
|
||||
const bool ret = !!ReleaseMutex( mutex );
|
||||
|
||||
/* We can't ASSERT here, since this is called from checkpoints, which is
|
||||
* called from ASSERT. */
|
||||
if( !ret )
|
||||
sm_crash( werr_ssprintf( GetLastError(), "ReleaseMutex failed" ) );
|
||||
}
|
||||
|
||||
uint64_t MutexImpl_Win32::GetLockedByThreadId() const
|
||||
{
|
||||
return LockedBy;
|
||||
}
|
||||
|
||||
uint64_t GetThisThreadId()
|
||||
{
|
||||
return GetCurrentThreadId();
|
||||
}
|
||||
|
||||
uint64_t GetInvalidThreadId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
MutexImpl *MakeMutex( RageMutex *pParent )
|
||||
{
|
||||
return new MutexImpl_Win32( pParent );
|
||||
}
|
||||
|
||||
/*
|
||||
* (c) 2001-2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, and/or sell copies of the Software, and to permit persons to
|
||||
* whom the Software is furnished to do so, provided that the above
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
||||
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
||||
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef THREADS_WIN32_H
|
||||
#define THREADS_WIN32_H
|
||||
|
||||
#include "Threads.h"
|
||||
#include <windows.h>
|
||||
|
||||
class ThreadImpl_Win32: public ThreadImpl
|
||||
{
|
||||
public:
|
||||
HANDLE ThreadHandle;
|
||||
DWORD ThreadId;
|
||||
|
||||
int (*m_pFunc)( void *pData );
|
||||
void *m_pData;
|
||||
|
||||
void Halt( bool Kill );
|
||||
void Resume();
|
||||
uint64_t GetThreadId() const;
|
||||
uint64_t GetCrashHandle() const;
|
||||
int Wait();
|
||||
};
|
||||
|
||||
struct MutexImpl_Win32: public MutexImpl
|
||||
{
|
||||
uint64_t LockedBy;
|
||||
volatile int LockCnt;
|
||||
|
||||
HANDLE mutex;
|
||||
|
||||
MutexImpl_Win32( RageMutex *parent );
|
||||
~MutexImpl_Win32();
|
||||
|
||||
bool Lock();
|
||||
void Unlock();
|
||||
uint64_t GetLockedByThreadId() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* (c) 2001-2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, and/or sell copies of the Software, and to permit persons to
|
||||
* whom the Software is furnished to do so, provided that the above
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
||||
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
||||
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
Reference in New Issue
Block a user