ipc/chromium/src/base/platform_thread_win.cc

changeset 0
6474c204b198
     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 +}

mercurial