nim_duilib/base/thread/thread_win.cpp
jiajia_deng 4933d1f2bc Remove dependency on shared
Signed-off-by: jiajia_deng <2894220@gmail.com>
2019-09-20 16:27:58 +08:00

158 lines
3.0 KiB
C++

// Copyright (c) 2011, NetEase Inc. All rights reserved.
//
// Author: rl
// Date: 2011/6/11
//
// Thread implementation on windows platform.
#include "base/thread/thread.h"
#if defined(OS_WIN)
#include <assert.h>
namespace nbase
{
// Set a Thread Name in Native Code
// http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
#if defined(OS_WIN) && defined(COMPILER_MSVC)
const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
// Note that the thread name is copied to the thread so that the memory for the
// threadName parameter can be released.
void SetThreadName(DWORD thread_id, const char* name)
{
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = name;
info.dwThreadID = thread_id;
info.dwFlags = 0;
__try {
RaiseException(MS_VC_EXCEPTION,
0,
sizeof(info)/sizeof(ULONG_PTR),
(ULONG_PTR*)&info);
} __except(EXCEPTION_EXECUTE_HANDLER) {
//
}
}
#endif
Thread::Thread()
{
thread_id_ = 0;
thread_handle_ = NULL;
thread_priority_ = kThreadPriorityDefault;
}
Thread::~Thread()
{
Close();
}
bool Thread::Create()
{
// create thread first
thread_handle_ = (HANDLE)_beginthreadex(NULL,
0, ThreadProcFunc, this, 0, (unsigned*)&thread_id_);
if (thread_handle_ < (HANDLE)2)
{
thread_handle_ = NULL;
thread_id_ = 0;
}
// if thread need set priority
if (thread_priority_ > kThreadPriorityDefault)
{
// set the thread priority
int pri = THREAD_PRIORITY_BELOW_NORMAL;
if (thread_priority_ == kThreadPriorityLow)
pri = THREAD_PRIORITY_LOWEST;
else if (thread_priority_ == kThreadPriorityNormal)
pri = THREAD_PRIORITY_BELOW_NORMAL;
else if (thread_priority_ == kThreadPriorityHigh)
pri = THREAD_PRIORITY_HIGHEST;
else if (thread_priority_ == kThreadPriorityRealtime)
pri = THREAD_PRIORITY_TIME_CRITICAL;
SetThreadPriority (thread_handle_, pri);
}
return thread_handle_ > (HANDLE)1;
}
void Thread::Close()
{
if (thread_handle_)
{
if (WAIT_OBJECT_0 == WaitForSingleObject(thread_handle_, INFINITE))
{
::CloseHandle(thread_handle_);
thread_handle_ = NULL;
thread_id_ = 0;
}
else
{
Terminate();
}
}
}
void Thread::Terminate()
{
if (thread_handle_)
{
::TerminateThread(thread_handle_, 0);
::CloseHandle(thread_handle_);
thread_handle_ = NULL;
thread_id_ = 0;
}
}
// static
void Thread::Sleep(int duration_ms)
{
::Sleep(duration_ms);
}
// static
void Thread::YieldThread()
{
::Sleep(0);
}
// static
ThreadId Thread::CurrentId()
{
return GetCurrentThreadId();
}
uint32_t __stdcall Thread::ThreadProcFunc(void *arg)
{
Thread* the_thread = (Thread*)arg;
assert(the_thread);
if (the_thread != NULL)
{
the_thread->Run();
}
_endthreadex(0);
return 0;
}
} // namespace nbase
#endif // OS_POSIX