1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/win/scoped_handle.h"
6
7#include <map>
8
9#include "base/debug/alias.h"
10#include "base/lazy_instance.h"
11#include "base/synchronization/lock.h"
12#include "base/win/windows_version.h"
13
14namespace {
15
16struct Info {
17  const void* owner;
18  const void* pc1;
19  const void* pc2;
20  DWORD thread_id;
21};
22typedef std::map<HANDLE, Info> HandleMap;
23
24base::LazyInstance<HandleMap>::Leaky g_handle_map = LAZY_INSTANCE_INITIALIZER;
25base::LazyInstance<base::Lock>::Leaky g_lock = LAZY_INSTANCE_INITIALIZER;
26
27}  // namespace
28
29namespace base {
30namespace win {
31
32// Static.
33void VerifierTraits::StartTracking(HANDLE handle, const void* owner,
34                                   const void* pc1, const void* pc2) {
35  // Grab the thread id before the lock.
36  DWORD thread_id = GetCurrentThreadId();
37
38  AutoLock lock(g_lock.Get());
39
40  Info handle_info = { owner, pc1, pc2, thread_id };
41  std::pair<HANDLE, Info> item(handle, handle_info);
42  std::pair<HandleMap::iterator, bool> result = g_handle_map.Get().insert(item);
43  if (!result.second) {
44    Info other = result.first->second;
45    debug::Alias(&other);
46    CHECK(false);
47  }
48}
49
50// Static.
51void VerifierTraits::StopTracking(HANDLE handle, const void* owner,
52                                  const void* pc1, const void* pc2) {
53  AutoLock lock(g_lock.Get());
54  HandleMap::iterator i = g_handle_map.Get().find(handle);
55  if (i == g_handle_map.Get().end())
56    CHECK(false);
57
58  Info other = i->second;
59  if (other.owner != owner) {
60    debug::Alias(&other);
61    CHECK(false);
62  }
63
64  g_handle_map.Get().erase(i);
65}
66
67}  // namespace win
68}  // namespace base
69