blob: 00efdc13cee1c17ac3a67536d8aa272da6ac0407 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
[email protected]e9ba26d2008-08-21 09:46:324
5#include "base/platform_thread.h"
6
7#include <process.h>
8
9#include "base/logging.h"
10#include "base/win_util.h"
11
12namespace {
13
14// The information on how to set the thread name comes from
15// a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx
16const DWORD kVCThreadNameException = 0x406D1388;
17
18typedef struct tagTHREADNAME_INFO {
19 DWORD dwType; // Must be 0x1000.
20 LPCSTR szName; // Pointer to name (in user addr space).
21 DWORD dwThreadID; // Thread ID (-1=caller thread).
22 DWORD dwFlags; // Reserved for future use, must be zero.
23} THREADNAME_INFO;
24
25unsigned __stdcall ThreadFunc(void* closure) {
26 PlatformThread::Delegate* delegate =
27 static_cast<PlatformThread::Delegate*>(closure);
28 delegate->ThreadMain();
29 return NULL;
30}
31
32} // namespace
33
34// static
35int PlatformThread::CurrentId() {
36 return GetCurrentThreadId();
37}
38
39// static
40void PlatformThread::YieldCurrentThread() {
41 ::Sleep(0);
42}
43
44// static
45void PlatformThread::Sleep(int duration_ms) {
46 ::Sleep(duration_ms);
47}
48
49// static
[email protected]7d0f94452008-08-25 13:54:1850void PlatformThread::SetName(const char* name) {
[email protected]e9ba26d2008-08-21 09:46:3251 THREADNAME_INFO info;
52 info.dwType = 0x1000;
53 info.szName = name;
[email protected]7d0f94452008-08-25 13:54:1854 info.dwThreadID = CurrentId();
[email protected]e9ba26d2008-08-21 09:46:3255 info.dwFlags = 0;
56
57 __try {
58 RaiseException(kVCThreadNameException, 0, sizeof(info)/sizeof(DWORD),
59 reinterpret_cast<DWORD_PTR*>(&info));
60 } __except(EXCEPTION_CONTINUE_EXECUTION) {
61 }
62}
63
64// static
65bool PlatformThread::Create(size_t stack_size, Delegate* delegate,
66 PlatformThreadHandle* thread_handle) {
67 unsigned int flags = 0;
68 if (stack_size > 0 && win_util::GetWinVersion() >= win_util::WINVERSION_XP) {
69 flags = STACK_SIZE_PARAM_IS_A_RESERVATION;
70 } else {
71 stack_size = 0;
72 }
73
74 *thread_handle = reinterpret_cast<PlatformThreadHandle>(_beginthreadex(
75 NULL, stack_size, ThreadFunc, delegate, flags, NULL));
76 return *thread_handle != NULL;
77}
78
79// static
80void PlatformThread::Join(PlatformThreadHandle thread_handle) {
81 DCHECK(thread_handle);
82
83 // Wait for the thread to exit. It should already have terminated but make
84 // sure this assumption is valid.
85 DWORD result = WaitForSingleObject(thread_handle, INFINITE);
86 DCHECK_EQ(WAIT_OBJECT_0, result);
87
88 CloseHandle(thread_handle);
89}
license.botbf09a502008-08-24 00:55:5590