Home | History | Annotate | Download | only in win
      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 
     14 namespace {
     15 
     16 struct Info {
     17   const void* owner;
     18   const void* pc1;
     19   const void* pc2;
     20   DWORD thread_id;
     21 };
     22 typedef std::map<HANDLE, Info> HandleMap;
     23 
     24 base::LazyInstance<HandleMap>::Leaky g_handle_map = LAZY_INSTANCE_INITIALIZER;
     25 base::LazyInstance<base::Lock>::Leaky g_lock = LAZY_INSTANCE_INITIALIZER;
     26 
     27 }  // namespace
     28 
     29 namespace base {
     30 namespace win {
     31 
     32 // Static.
     33 void 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.
     51 void 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