1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/platform_thread_win.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,105 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "base/platform_thread.h" 1.9 + 1.10 +#include "base/logging.h" 1.11 +#include "base/win_util.h" 1.12 + 1.13 +namespace { 1.14 + 1.15 +// The information on how to set the thread name comes from 1.16 +// a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx 1.17 +const DWORD kVCThreadNameException = 0x406D1388; 1.18 + 1.19 +typedef struct tagTHREADNAME_INFO { 1.20 + DWORD dwType; // Must be 0x1000. 1.21 + LPCSTR szName; // Pointer to name (in user addr space). 1.22 + DWORD dwThreadID; // Thread ID (-1=caller thread). 1.23 + DWORD dwFlags; // Reserved for future use, must be zero. 1.24 +} THREADNAME_INFO; 1.25 + 1.26 +DWORD __stdcall ThreadFunc(void* closure) { 1.27 + PlatformThread::Delegate* delegate = 1.28 + static_cast<PlatformThread::Delegate*>(closure); 1.29 + delegate->ThreadMain(); 1.30 + return 0; 1.31 +} 1.32 + 1.33 +} // namespace 1.34 + 1.35 +// static 1.36 +PlatformThreadId PlatformThread::CurrentId() { 1.37 + return GetCurrentThreadId(); 1.38 +} 1.39 + 1.40 +// static 1.41 +void PlatformThread::YieldCurrentThread() { 1.42 + ::Sleep(0); 1.43 +} 1.44 + 1.45 +// static 1.46 +void PlatformThread::Sleep(int duration_ms) { 1.47 + ::Sleep(duration_ms); 1.48 +} 1.49 + 1.50 +// static 1.51 +void PlatformThread::SetName(const char* name) { 1.52 + // The debugger needs to be around to catch the name in the exception. If 1.53 + // there isn't a debugger, we are just needlessly throwing an exception. 1.54 + if (!::IsDebuggerPresent()) 1.55 + return; 1.56 + 1.57 + THREADNAME_INFO info; 1.58 + info.dwType = 0x1000; 1.59 + info.szName = name; 1.60 + info.dwThreadID = CurrentId(); 1.61 + info.dwFlags = 0; 1.62 + 1.63 + MOZ_SEH_TRY { 1.64 + RaiseException(kVCThreadNameException, 0, sizeof(info)/sizeof(DWORD), 1.65 + reinterpret_cast<DWORD_PTR*>(&info)); 1.66 + } MOZ_SEH_EXCEPT(EXCEPTION_CONTINUE_EXECUTION) { 1.67 + } 1.68 +} 1.69 + 1.70 +// static 1.71 +bool PlatformThread::Create(size_t stack_size, Delegate* delegate, 1.72 + PlatformThreadHandle* thread_handle) { 1.73 + unsigned int flags = 0; 1.74 + if (stack_size > 0 && win_util::GetWinVersion() >= win_util::WINVERSION_XP) { 1.75 + flags = STACK_SIZE_PARAM_IS_A_RESERVATION; 1.76 + } else { 1.77 + stack_size = 0; 1.78 + } 1.79 + 1.80 + // Using CreateThread here vs _beginthreadex makes thread creation a bit 1.81 + // faster and doesn't require the loader lock to be available. Our code will 1.82 + // have to work running on CreateThread() threads anyway, since we run code 1.83 + // on the Windows thread pool, etc. For some background on the difference: 1.84 + // http://www.microsoft.com/msj/1099/win32/win321099.aspx 1.85 + *thread_handle = CreateThread( 1.86 + NULL, stack_size, ThreadFunc, delegate, flags, NULL); 1.87 + return *thread_handle != NULL; 1.88 +} 1.89 + 1.90 +// static 1.91 +bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) { 1.92 + PlatformThreadHandle thread_handle; 1.93 + bool result = Create(stack_size, delegate, &thread_handle); 1.94 + CloseHandle(thread_handle); 1.95 + return result; 1.96 +} 1.97 + 1.98 +// static 1.99 +void PlatformThread::Join(PlatformThreadHandle thread_handle) { 1.100 + DCHECK(thread_handle); 1.101 + 1.102 + // Wait for the thread to exit. It should already have terminated but make 1.103 + // sure this assumption is valid. 1.104 + DWORD result = WaitForSingleObject(thread_handle, INFINITE); 1.105 + DCHECK_EQ(WAIT_OBJECT_0, result); 1.106 + 1.107 + CloseHandle(thread_handle); 1.108 +}