Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_WIN_SCOPED_HANDLE_H_ | 5 #ifndef BASE_WIN_SCOPED_HANDLE_H_ |
| 6 #define BASE_WIN_SCOPED_HANDLE_H_ | 6 #define BASE_WIN_SCOPED_HANDLE_H_ |
| 7 #pragma once | 7 #pragma once |
| 8 | 8 |
| 9 #include <windows.h> | 9 #include <windows.h> |
| 10 | 10 |
| 11 #include "base/base_export.h" | |
| 11 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/location.h" | |
| 12 #include "base/logging.h" | 14 #include "base/logging.h" |
| 13 | 15 |
| 14 namespace base { | 16 namespace base { |
| 15 namespace win { | 17 namespace win { |
| 16 | 18 |
| 17 // Generic wrapper for raw handles that takes care of closing handles | 19 // Generic wrapper for raw handles that takes care of closing handles |
| 18 // automatically. The class interface follows the style of | 20 // automatically. The class interface follows the style of |
| 19 // the ScopedStdioHandle class with a few additions: | 21 // the ScopedStdioHandle class with a few additions: |
| 20 // - IsValid() method can tolerate multiple invalid handle values such as NULL | 22 // - IsValid() method can tolerate multiple invalid handle values such as NULL |
| 21 // and INVALID_HANDLE_VALUE (-1) for Win32 handles. | 23 // and INVALID_HANDLE_VALUE (-1) for Win32 handles. |
| 22 // - Receive() method allows to receive a handle value from a function that | 24 // - Receive() method allows to receive a handle value from a function that |
| 23 // takes a raw handle pointer only. | 25 // takes a raw handle pointer only. |
| 24 template <class Traits> | 26 template <class Traits, class Verifier> |
| 25 class GenericScopedHandle { | 27 class GenericScopedHandle { |
| 26 public: | 28 public: |
| 27 typedef typename Traits::Handle Handle; | 29 typedef typename Traits::Handle Handle; |
| 28 | 30 |
| 29 GenericScopedHandle() : handle_(Traits::NullHandle()) {} | 31 GenericScopedHandle() : handle_(Traits::NullHandle()) {} |
| 30 | 32 |
| 31 explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) { | 33 explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) { |
| 32 Set(handle); | 34 Set(handle); |
| 33 } | 35 } |
| 34 | 36 |
| 35 ~GenericScopedHandle() { | 37 ~GenericScopedHandle() { |
| 36 Close(); | 38 Close(); |
| 37 } | 39 } |
| 38 | 40 |
| 39 bool IsValid() const { | 41 bool IsValid() const { |
| 40 return Traits::IsHandleValid(handle_); | 42 return Traits::IsHandleValid(handle_); |
| 41 } | 43 } |
| 42 | 44 |
| 43 void Set(Handle handle) { | 45 void Set(Handle handle) { |
| 44 if (handle_ != handle) { | 46 if (handle_ != handle) { |
| 45 Close(); | 47 Close(); |
| 46 | 48 |
| 47 if (Traits::IsHandleValid(handle)) { | 49 if (Traits::IsHandleValid(handle)) { |
| 48 handle_ = handle; | 50 handle_ = handle; |
| 51 Verifier::StartTracking(handle, this, | |
| 52 tracked_objects::GetProgramCounter()); | |
| 49 } | 53 } |
| 50 } | 54 } |
| 51 } | 55 } |
| 52 | 56 |
| 53 Handle Get() const { | 57 Handle Get() const { |
| 54 return handle_; | 58 return handle_; |
| 55 } | 59 } |
| 56 | 60 |
| 57 operator Handle() const { | 61 operator Handle() const { |
| 58 return handle_; | 62 return handle_; |
| 59 } | 63 } |
| 60 | 64 |
| 61 Handle* Receive() { | 65 Handle* Receive() { |
| 62 DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL"; | 66 DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL"; |
| 67 | |
| 68 // We cannot track this case :(. Just tell the verifier about it. | |
|
alexeypa (please no reviews)
2012/05/30 20:19:30
This is one of the most common ways of initializin
rvargas (doing something else)
2012/05/30 21:39:01
That is both unfortunate and surprising (given tha
| |
| 69 Verifier::StartTracking(INVALID_HANDLE_VALUE, this, | |
| 70 tracked_objects::GetProgramCounter()); | |
| 63 return &handle_; | 71 return &handle_; |
| 64 } | 72 } |
| 65 | 73 |
| 66 // Transfers ownership away from this object. | 74 // Transfers ownership away from this object. |
| 67 Handle Take() { | 75 Handle Take() { |
| 68 Handle temp = handle_; | 76 Handle temp = handle_; |
| 69 handle_ = Traits::NullHandle(); | 77 handle_ = Traits::NullHandle(); |
| 78 Verifier::StopTracking(temp, this, tracked_objects::GetProgramCounter()); | |
| 70 return temp; | 79 return temp; |
| 71 } | 80 } |
| 72 | 81 |
| 73 // Explicitly closes the owned handle. | 82 // Explicitly closes the owned handle. |
| 74 void Close() { | 83 void Close() { |
| 75 if (Traits::IsHandleValid(handle_)) { | 84 if (Traits::IsHandleValid(handle_)) { |
| 76 if (!Traits::CloseHandle(handle_)) { | 85 if (!Traits::CloseHandle(handle_)) { |
| 77 CHECK(false); | 86 CHECK(false); |
| 78 } | 87 } |
| 88 Verifier::StopTracking(handle_, this, | |
| 89 tracked_objects::GetProgramCounter()); | |
| 79 handle_ = Traits::NullHandle(); | 90 handle_ = Traits::NullHandle(); |
| 80 } | 91 } |
| 81 } | 92 } |
| 82 | 93 |
| 83 private: | 94 private: |
| 84 Handle handle_; | 95 Handle handle_; |
| 85 | 96 |
| 86 DISALLOW_COPY_AND_ASSIGN(GenericScopedHandle); | 97 DISALLOW_COPY_AND_ASSIGN(GenericScopedHandle); |
| 87 }; | 98 }; |
| 88 | 99 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 103 | 114 |
| 104 // Returns NULL handle value. | 115 // Returns NULL handle value. |
| 105 static HANDLE NullHandle() { | 116 static HANDLE NullHandle() { |
| 106 return NULL; | 117 return NULL; |
| 107 } | 118 } |
| 108 | 119 |
| 109 private: | 120 private: |
| 110 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits); | 121 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits); |
| 111 }; | 122 }; |
| 112 | 123 |
| 113 typedef GenericScopedHandle<HandleTraits> ScopedHandle; | 124 // Do-nothing verifier. |
| 125 class DummyVerifierTraits { | |
| 126 public: | |
| 127 typedef HANDLE Handle; | |
| 128 | |
| 129 static void StartTracking(HANDLE handle, const void* owner, const void* pc) {} | |
| 130 static void StopTracking(HANDLE handle, const void* owner, const void* pc) {} | |
| 131 | |
| 132 private: | |
| 133 DISALLOW_IMPLICIT_CONSTRUCTORS(DummyVerifierTraits); | |
| 134 }; | |
| 135 | |
| 136 // Performs actual run-time tracking. | |
| 137 class BASE_EXPORT VerifierTraits { | |
| 138 public: | |
| 139 typedef HANDLE Handle; | |
| 140 | |
| 141 static void StartTracking(HANDLE handle, const void* owner, const void* pc); | |
| 142 static void StopTracking(HANDLE handle, const void* owner, const void* pc); | |
| 143 | |
| 144 private: | |
| 145 DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits); | |
| 146 }; | |
| 147 | |
| 148 typedef GenericScopedHandle<HandleTraits, DummyVerifierTraits> ScopedHandle; | |
| 114 | 149 |
| 115 } // namespace win | 150 } // namespace win |
| 116 } // namespace base | 151 } // namespace base |
| 117 | 152 |
| 118 #endif // BASE_SCOPED_HANDLE_WIN_H_ | 153 #endif // BASE_SCOPED_HANDLE_WIN_H_ |
| OLD | NEW |