diff options
Diffstat (limited to 'js/src/threading/windows/MutexImpl.cpp')
-rw-r--r-- | js/src/threading/windows/MutexImpl.cpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/js/src/threading/windows/MutexImpl.cpp b/js/src/threading/windows/MutexImpl.cpp new file mode 100644 index 000000000..385d1c8de --- /dev/null +++ b/js/src/threading/windows/MutexImpl.cpp @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/DebugOnly.h" + +#include "jswin.h" + +#include "js/Utility.h" + +#include "threading/Mutex.h" +#include "threading/windows/MutexPlatformData.h" + +namespace { + +// We build with a toolkit that supports WinXP, so we have to probe +// for modern features at runtime. This is necessary because Vista and +// later automatically allocate and subsequently leak a debug info +// object for each critical section that we allocate unless we tell it +// not to. In order to tell it not to, we need the extra flags field +// provided by the Ex version of InitializeCriticalSection. +struct MutexNativeImports +{ + using InitializeCriticalSectionExT = BOOL (WINAPI*)(CRITICAL_SECTION*, DWORD, DWORD); + InitializeCriticalSectionExT InitializeCriticalSectionEx; + + MutexNativeImports() { + HMODULE kernel32_dll = GetModuleHandle("kernel32.dll"); + MOZ_RELEASE_ASSERT(kernel32_dll != NULL); + InitializeCriticalSectionEx = reinterpret_cast<InitializeCriticalSectionExT>( + GetProcAddress(kernel32_dll, "InitializeCriticalSectionEx")); + } + + bool hasInitializeCriticalSectionEx() const { + return InitializeCriticalSectionEx; + } +}; + +static MutexNativeImports NativeImports; + +} // (anonymous namespace) + +js::detail::MutexImpl::MutexImpl() +{ + AutoEnterOOMUnsafeRegion oom; + platformData_ = js_new<PlatformData>(); + if (!platformData_) + oom.crash("js::Mutex::Mutex"); + + // This number was adopted from NSPR. + const static DWORD LockSpinCount = 1500; + BOOL r; + if (NativeImports.hasInitializeCriticalSectionEx()) { + r = NativeImports.InitializeCriticalSectionEx(&platformData()->criticalSection, + LockSpinCount, + CRITICAL_SECTION_NO_DEBUG_INFO); + } else { + r = InitializeCriticalSectionAndSpinCount(&platformData()->criticalSection, + LockSpinCount); + } + MOZ_RELEASE_ASSERT(r); +} + +js::detail::MutexImpl::~MutexImpl() +{ + if (!platformData_) + return; + + DeleteCriticalSection(&platformData()->criticalSection); + js_delete(platformData()); +} + +void +js::detail::MutexImpl::lock() +{ + EnterCriticalSection(&platformData()->criticalSection); +} + +void +js::detail::MutexImpl::unlock() +{ + LeaveCriticalSection(&platformData()->criticalSection); +} |