| Index: base/win/scoped_handle.cc
|
| diff --git a/base/win/scoped_handle.cc b/base/win/scoped_handle.cc
|
| deleted file mode 100644
|
| index ce944e43b9fe3fb30a7b699863efeb9ab0c8ee13..0000000000000000000000000000000000000000
|
| --- a/base/win/scoped_handle.cc
|
| +++ /dev/null
|
| @@ -1,257 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "base/win/scoped_handle.h"
|
| -
|
| -#include <unordered_map>
|
| -
|
| -#include "base/debug/alias.h"
|
| -#include "base/hash.h"
|
| -#include "base/lazy_instance.h"
|
| -#include "base/logging.h"
|
| -#include "base/synchronization/lock_impl.h"
|
| -
|
| -extern "C" {
|
| -__declspec(dllexport) void* GetHandleVerifier();
|
| -typedef void* (*GetHandleVerifierFn)();
|
| -}
|
| -
|
| -namespace {
|
| -
|
| -struct HandleHash {
|
| - size_t operator()(const HANDLE& handle) const {
|
| - char buffer[sizeof(handle)];
|
| - memcpy(buffer, &handle, sizeof(handle));
|
| - return base::Hash(buffer, sizeof(buffer));
|
| - }
|
| -};
|
| -
|
| -struct Info {
|
| - const void* owner;
|
| - const void* pc1;
|
| - const void* pc2;
|
| - DWORD thread_id;
|
| -};
|
| -typedef std::unordered_map<HANDLE, Info, HandleHash> HandleMap;
|
| -
|
| -// g_lock protects the handle map and setting g_active_verifier.
|
| -typedef base::internal::LockImpl NativeLock;
|
| -base::LazyInstance<NativeLock>::Leaky g_lock = LAZY_INSTANCE_INITIALIZER;
|
| -
|
| -bool CloseHandleWrapper(HANDLE handle) {
|
| - if (!::CloseHandle(handle))
|
| - CHECK(false);
|
| - return true;
|
| -}
|
| -
|
| -// Simple automatic locking using a native critical section so it supports
|
| -// recursive locking.
|
| -class AutoNativeLock {
|
| - public:
|
| - explicit AutoNativeLock(NativeLock& lock) : lock_(lock) {
|
| - lock_.Lock();
|
| - }
|
| -
|
| - ~AutoNativeLock() {
|
| - lock_.Unlock();
|
| - }
|
| -
|
| - private:
|
| - NativeLock& lock_;
|
| - DISALLOW_COPY_AND_ASSIGN(AutoNativeLock);
|
| -};
|
| -
|
| -// Implements the actual object that is verifying handles for this process.
|
| -// The active instance is shared across the module boundary but there is no
|
| -// way to delete this object from the wrong side of it (or any side, actually).
|
| -class ActiveVerifier {
|
| - public:
|
| - explicit ActiveVerifier(bool enabled)
|
| - : enabled_(enabled), closing_(false), lock_(g_lock.Pointer()) {
|
| - }
|
| -
|
| - // Retrieves the current verifier.
|
| - static ActiveVerifier* Get();
|
| -
|
| - // The methods required by HandleTraits. They are virtual because we need to
|
| - // forward the call execution to another module, instead of letting the
|
| - // compiler call the version that is linked in the current module.
|
| - virtual bool CloseHandle(HANDLE handle);
|
| - virtual void StartTracking(HANDLE handle, const void* owner,
|
| - const void* pc1, const void* pc2);
|
| - virtual void StopTracking(HANDLE handle, const void* owner,
|
| - const void* pc1, const void* pc2);
|
| - virtual void Disable();
|
| - virtual void OnHandleBeingClosed(HANDLE handle);
|
| -
|
| - private:
|
| - ~ActiveVerifier(); // Not implemented.
|
| -
|
| - static void InstallVerifier();
|
| -
|
| - bool enabled_;
|
| - bool closing_;
|
| - NativeLock* lock_;
|
| - HandleMap map_;
|
| - DISALLOW_COPY_AND_ASSIGN(ActiveVerifier);
|
| -};
|
| -ActiveVerifier* g_active_verifier = NULL;
|
| -
|
| -// static
|
| -ActiveVerifier* ActiveVerifier::Get() {
|
| - if (!g_active_verifier)
|
| - ActiveVerifier::InstallVerifier();
|
| -
|
| - return g_active_verifier;
|
| -}
|
| -
|
| -// static
|
| -void ActiveVerifier::InstallVerifier() {
|
| -#if defined(COMPONENT_BUILD)
|
| - AutoNativeLock lock(g_lock.Get());
|
| - g_active_verifier = new ActiveVerifier(true);
|
| -#else
|
| - // If you are reading this, wondering why your process seems deadlocked, take
|
| - // a look at your DllMain code and remove things that should not be done
|
| - // there, like doing whatever gave you that nice windows handle you are trying
|
| - // to store in a ScopedHandle.
|
| - HMODULE main_module = ::GetModuleHandle(NULL);
|
| - GetHandleVerifierFn get_handle_verifier =
|
| - reinterpret_cast<GetHandleVerifierFn>(::GetProcAddress(
|
| - main_module, "GetHandleVerifier"));
|
| -
|
| - if (!get_handle_verifier) {
|
| - g_active_verifier = new ActiveVerifier(false);
|
| - return;
|
| - }
|
| -
|
| - ActiveVerifier* verifier =
|
| - reinterpret_cast<ActiveVerifier*>(get_handle_verifier());
|
| -
|
| - // This lock only protects against races in this module, which is fine.
|
| - AutoNativeLock lock(g_lock.Get());
|
| - g_active_verifier = verifier ? verifier : new ActiveVerifier(true);
|
| -#endif
|
| -}
|
| -
|
| -bool ActiveVerifier::CloseHandle(HANDLE handle) {
|
| - if (!enabled_)
|
| - return CloseHandleWrapper(handle);
|
| -
|
| - AutoNativeLock lock(*lock_);
|
| - closing_ = true;
|
| - CloseHandleWrapper(handle);
|
| - closing_ = false;
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void ActiveVerifier::StartTracking(HANDLE handle, const void* owner,
|
| - const void* pc1, const void* pc2) {
|
| - if (!enabled_)
|
| - return;
|
| -
|
| - // Idea here is to make our handles non-closable until we close it ourselves.
|
| - // Handles provided could be totally fabricated especially through our
|
| - // unittest, we are ignoring that for now by not checking return value.
|
| - ::SetHandleInformation(handle, HANDLE_FLAG_PROTECT_FROM_CLOSE,
|
| - HANDLE_FLAG_PROTECT_FROM_CLOSE);
|
| -
|
| - // Grab the thread id before the lock.
|
| - DWORD thread_id = GetCurrentThreadId();
|
| -
|
| - AutoNativeLock lock(*lock_);
|
| -
|
| - Info handle_info = { owner, pc1, pc2, thread_id };
|
| - std::pair<HANDLE, Info> item(handle, handle_info);
|
| - std::pair<HandleMap::iterator, bool> result = map_.insert(item);
|
| - if (!result.second) {
|
| - Info other = result.first->second;
|
| - base::debug::Alias(&other);
|
| - CHECK(false);
|
| - }
|
| -}
|
| -
|
| -void ActiveVerifier::StopTracking(HANDLE handle, const void* owner,
|
| - const void* pc1, const void* pc2) {
|
| - if (!enabled_)
|
| - return;
|
| -
|
| - // We expect handle to be protected till this point.
|
| - DWORD flags = 0;
|
| - if (::GetHandleInformation(handle, &flags)) {
|
| - CHECK_NE(0U, (flags & HANDLE_FLAG_PROTECT_FROM_CLOSE));
|
| -
|
| - // Unprotect handle so that it could be closed.
|
| - ::SetHandleInformation(handle, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0);
|
| - }
|
| -
|
| - AutoNativeLock lock(*lock_);
|
| - HandleMap::iterator i = map_.find(handle);
|
| - if (i == map_.end())
|
| - CHECK(false);
|
| -
|
| - Info other = i->second;
|
| - if (other.owner != owner) {
|
| - base::debug::Alias(&other);
|
| - CHECK(false);
|
| - }
|
| -
|
| - map_.erase(i);
|
| -}
|
| -
|
| -void ActiveVerifier::Disable() {
|
| - enabled_ = false;
|
| -}
|
| -
|
| -void ActiveVerifier::OnHandleBeingClosed(HANDLE handle) {
|
| - AutoNativeLock lock(*lock_);
|
| - if (closing_)
|
| - return;
|
| -
|
| - HandleMap::iterator i = map_.find(handle);
|
| - if (i == map_.end())
|
| - return;
|
| -
|
| - Info other = i->second;
|
| - base::debug::Alias(&other);
|
| - CHECK(false);
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -void* GetHandleVerifier() {
|
| - return g_active_verifier;
|
| -}
|
| -
|
| -namespace base {
|
| -namespace win {
|
| -
|
| -// Static.
|
| -bool HandleTraits::CloseHandle(HANDLE handle) {
|
| - return ActiveVerifier::Get()->CloseHandle(handle);
|
| -}
|
| -
|
| -// Static.
|
| -void VerifierTraits::StartTracking(HANDLE handle, const void* owner,
|
| - const void* pc1, const void* pc2) {
|
| - return ActiveVerifier::Get()->StartTracking(handle, owner, pc1, pc2);
|
| -}
|
| -
|
| -// Static.
|
| -void VerifierTraits::StopTracking(HANDLE handle, const void* owner,
|
| - const void* pc1, const void* pc2) {
|
| - return ActiveVerifier::Get()->StopTracking(handle, owner, pc1, pc2);
|
| -}
|
| -
|
| -void DisableHandleVerifier() {
|
| - return ActiveVerifier::Get()->Disable();
|
| -}
|
| -
|
| -void OnHandleBeingClosed(HANDLE handle) {
|
| - return ActiveVerifier::Get()->OnHandleBeingClosed(handle);
|
| -}
|
| -
|
| -} // namespace win
|
| -} // namespace base
|
|
|