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 |