michael@0: // Copyright (c) 2012 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #include "base/win/scoped_handle.h" michael@0: michael@0: #include michael@0: michael@0: #include "base/debug/alias.h" michael@0: #include "base/lazy_instance.h" michael@0: #include "base/synchronization/lock.h" michael@0: #include "base/win/windows_version.h" michael@0: michael@0: namespace { michael@0: michael@0: struct Info { michael@0: const void* owner; michael@0: const void* pc1; michael@0: const void* pc2; michael@0: DWORD thread_id; michael@0: }; michael@0: typedef std::map HandleMap; michael@0: michael@0: base::LazyInstance::Leaky g_handle_map = LAZY_INSTANCE_INITIALIZER; michael@0: base::LazyInstance::Leaky g_lock = LAZY_INSTANCE_INITIALIZER; michael@0: michael@0: } // namespace michael@0: michael@0: namespace base { michael@0: namespace win { michael@0: michael@0: // Static. michael@0: void VerifierTraits::StartTracking(HANDLE handle, const void* owner, michael@0: const void* pc1, const void* pc2) { michael@0: // Grab the thread id before the lock. michael@0: DWORD thread_id = GetCurrentThreadId(); michael@0: michael@0: AutoLock lock(g_lock.Get()); michael@0: michael@0: Info handle_info = { owner, pc1, pc2, thread_id }; michael@0: std::pair item(handle, handle_info); michael@0: std::pair result = g_handle_map.Get().insert(item); michael@0: if (!result.second) { michael@0: Info other = result.first->second; michael@0: debug::Alias(&other); michael@0: CHECK(false); michael@0: } michael@0: } michael@0: michael@0: // Static. michael@0: void VerifierTraits::StopTracking(HANDLE handle, const void* owner, michael@0: const void* pc1, const void* pc2) { michael@0: AutoLock lock(g_lock.Get()); michael@0: HandleMap::iterator i = g_handle_map.Get().find(handle); michael@0: if (i == g_handle_map.Get().end()) michael@0: CHECK(false); michael@0: michael@0: Info other = i->second; michael@0: if (other.owner != owner) { michael@0: debug::Alias(&other); michael@0: CHECK(false); michael@0: } michael@0: michael@0: g_handle_map.Get().erase(i); michael@0: } michael@0: michael@0: } // namespace win michael@0: } // namespace base