| 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/base_export.h" |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 | 15 |
| 16 namespace base { | 16 namespace base { |
| 17 namespace win { | 17 namespace win { |
| 18 | 18 |
| 19 // TODO(rvargas): remove this with the rest of the verifier. |
| 20 #if defined(COMPILER_MSVC) |
| 21 // MSDN says to #include <intrin.h>, but that breaks the VS2005 build. |
| 22 extern "C" { |
| 23 void* _ReturnAddress(); |
| 24 } |
| 25 #define BASE_WIN_GET_CALLER _ReturnAddress() |
| 26 #elif defined(COMPILER_GCC) |
| 27 #define BASE_WIN_GET_CALLER __builtin_extract_return_addr(\\ |
| 28 __builtin_return_address(0)) |
| 29 #endif |
| 30 |
| 19 // Generic wrapper for raw handles that takes care of closing handles | 31 // Generic wrapper for raw handles that takes care of closing handles |
| 20 // automatically. The class interface follows the style of | 32 // automatically. The class interface follows the style of |
| 21 // the ScopedStdioHandle class with a few additions: | 33 // the ScopedStdioHandle class with a few additions: |
| 22 // - IsValid() method can tolerate multiple invalid handle values such as NULL | 34 // - IsValid() method can tolerate multiple invalid handle values such as NULL |
| 23 // and INVALID_HANDLE_VALUE (-1) for Win32 handles. | 35 // and INVALID_HANDLE_VALUE (-1) for Win32 handles. |
| 24 // - Receive() method allows to receive a handle value from a function that | 36 // - Receive() method allows to receive a handle value from a function that |
| 25 // takes a raw handle pointer only. | 37 // takes a raw handle pointer only. |
| 26 template <class Traits, class Verifier> | 38 template <class Traits, class Verifier> |
| 27 class GenericScopedHandle { | 39 class GenericScopedHandle { |
| 28 public: | 40 public: |
| (...skipping 12 matching lines...) Expand all Loading... |
| 41 bool IsValid() const { | 53 bool IsValid() const { |
| 42 return Traits::IsHandleValid(handle_); | 54 return Traits::IsHandleValid(handle_); |
| 43 } | 55 } |
| 44 | 56 |
| 45 void Set(Handle handle) { | 57 void Set(Handle handle) { |
| 46 if (handle_ != handle) { | 58 if (handle_ != handle) { |
| 47 Close(); | 59 Close(); |
| 48 | 60 |
| 49 if (Traits::IsHandleValid(handle)) { | 61 if (Traits::IsHandleValid(handle)) { |
| 50 handle_ = handle; | 62 handle_ = handle; |
| 51 Verifier::StartTracking(handle, this, | 63 Verifier::StartTracking(handle, this, BASE_WIN_GET_CALLER, |
| 52 tracked_objects::GetProgramCounter()); | 64 tracked_objects::GetProgramCounter()); |
| 53 } | 65 } |
| 54 } | 66 } |
| 55 } | 67 } |
| 56 | 68 |
| 57 Handle Get() const { | 69 Handle Get() const { |
| 58 return handle_; | 70 return handle_; |
| 59 } | 71 } |
| 60 | 72 |
| 61 operator Handle() const { | 73 operator Handle() const { |
| 62 return handle_; | 74 return handle_; |
| 63 } | 75 } |
| 64 | 76 |
| 65 Handle* Receive() { | 77 Handle* Receive() { |
| 66 DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL"; | 78 DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL"; |
| 67 | 79 |
| 68 // We cannot track this case :(. Just tell the verifier about it. | 80 // We cannot track this case :(. Just tell the verifier about it. |
| 69 Verifier::StartTracking(INVALID_HANDLE_VALUE, this, | 81 Verifier::StartTracking(INVALID_HANDLE_VALUE, this, BASE_WIN_GET_CALLER, |
| 70 tracked_objects::GetProgramCounter()); | 82 tracked_objects::GetProgramCounter()); |
| 71 return &handle_; | 83 return &handle_; |
| 72 } | 84 } |
| 73 | 85 |
| 74 // Transfers ownership away from this object. | 86 // Transfers ownership away from this object. |
| 75 Handle Take() { | 87 Handle Take() { |
| 76 Handle temp = handle_; | 88 Handle temp = handle_; |
| 77 handle_ = Traits::NullHandle(); | 89 handle_ = Traits::NullHandle(); |
| 78 Verifier::StopTracking(temp, this, tracked_objects::GetProgramCounter()); | 90 Verifier::StopTracking(temp, this, BASE_WIN_GET_CALLER, |
| 91 tracked_objects::GetProgramCounter()); |
| 79 return temp; | 92 return temp; |
| 80 } | 93 } |
| 81 | 94 |
| 82 // Explicitly closes the owned handle. | 95 // Explicitly closes the owned handle. |
| 83 void Close() { | 96 void Close() { |
| 84 if (Traits::IsHandleValid(handle_)) { | 97 if (Traits::IsHandleValid(handle_)) { |
| 85 Verifier::StopTracking(handle_, this, | 98 Verifier::StopTracking(handle_, this, BASE_WIN_GET_CALLER, |
| 86 tracked_objects::GetProgramCounter()); | 99 tracked_objects::GetProgramCounter()); |
| 87 | 100 |
| 88 if (!Traits::CloseHandle(handle_)) | 101 if (!Traits::CloseHandle(handle_)) |
| 89 CHECK(false); | 102 CHECK(false); |
| 90 | 103 |
| 91 handle_ = Traits::NullHandle(); | 104 handle_ = Traits::NullHandle(); |
| 92 } | 105 } |
| 93 } | 106 } |
| 94 | 107 |
| 95 private: | 108 private: |
| 96 Handle handle_; | 109 Handle handle_; |
| 97 | 110 |
| 98 DISALLOW_COPY_AND_ASSIGN(GenericScopedHandle); | 111 DISALLOW_COPY_AND_ASSIGN(GenericScopedHandle); |
| 99 }; | 112 }; |
| 100 | 113 |
| 114 #undef BASE_WIN_GET_CALLER |
| 115 |
| 101 // The traits class for Win32 handles that can be closed via CloseHandle() API. | 116 // The traits class for Win32 handles that can be closed via CloseHandle() API. |
| 102 class HandleTraits { | 117 class HandleTraits { |
| 103 public: | 118 public: |
| 104 typedef HANDLE Handle; | 119 typedef HANDLE Handle; |
| 105 | 120 |
| 106 // Closes the handle. | 121 // Closes the handle. |
| 107 static bool CloseHandle(HANDLE handle) { | 122 static bool CloseHandle(HANDLE handle) { |
| 108 return ::CloseHandle(handle) != FALSE; | 123 return ::CloseHandle(handle) != FALSE; |
| 109 } | 124 } |
| 110 | 125 |
| 111 // Returns true if the handle value is valid. | 126 // Returns true if the handle value is valid. |
| 112 static bool IsHandleValid(HANDLE handle) { | 127 static bool IsHandleValid(HANDLE handle) { |
| 113 return handle != NULL && handle != INVALID_HANDLE_VALUE; | 128 return handle != NULL && handle != INVALID_HANDLE_VALUE; |
| 114 } | 129 } |
| 115 | 130 |
| 116 // Returns NULL handle value. | 131 // Returns NULL handle value. |
| 117 static HANDLE NullHandle() { | 132 static HANDLE NullHandle() { |
| 118 return NULL; | 133 return NULL; |
| 119 } | 134 } |
| 120 | 135 |
| 121 private: | 136 private: |
| 122 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits); | 137 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits); |
| 123 }; | 138 }; |
| 124 | 139 |
| 125 // Do-nothing verifier. | 140 // Do-nothing verifier. |
| 126 class DummyVerifierTraits { | 141 class DummyVerifierTraits { |
| 127 public: | 142 public: |
| 128 typedef HANDLE Handle; | 143 typedef HANDLE Handle; |
| 129 | 144 |
| 130 static void StartTracking(HANDLE handle, const void* owner, const void* pc) {} | 145 static void StartTracking(HANDLE handle, const void* owner, |
| 131 static void StopTracking(HANDLE handle, const void* owner, const void* pc) {} | 146 const void* pc1, const void* pc2) {} |
| 147 static void StopTracking(HANDLE handle, const void* owner, |
| 148 const void* pc1, const void* pc2) {} |
| 132 | 149 |
| 133 private: | 150 private: |
| 134 DISALLOW_IMPLICIT_CONSTRUCTORS(DummyVerifierTraits); | 151 DISALLOW_IMPLICIT_CONSTRUCTORS(DummyVerifierTraits); |
| 135 }; | 152 }; |
| 136 | 153 |
| 137 // Performs actual run-time tracking. | 154 // Performs actual run-time tracking. |
| 138 class BASE_EXPORT VerifierTraits { | 155 class BASE_EXPORT VerifierTraits { |
| 139 public: | 156 public: |
| 140 typedef HANDLE Handle; | 157 typedef HANDLE Handle; |
| 141 | 158 |
| 142 static void StartTracking(HANDLE handle, const void* owner, const void* pc); | 159 static void StartTracking(HANDLE handle, const void* owner, |
| 143 static void StopTracking(HANDLE handle, const void* owner, const void* pc); | 160 const void* pc1, const void* pc2); |
| 161 static void StopTracking(HANDLE handle, const void* owner, |
| 162 const void* pc1, const void* pc2); |
| 144 | 163 |
| 145 private: | 164 private: |
| 146 DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits); | 165 DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits); |
| 147 }; | 166 }; |
| 148 | 167 |
| 149 typedef GenericScopedHandle<HandleTraits, VerifierTraits> ScopedHandle; | 168 typedef GenericScopedHandle<HandleTraits, VerifierTraits> ScopedHandle; |
| 150 | 169 |
| 151 } // namespace win | 170 } // namespace win |
| 152 } // namespace base | 171 } // namespace base |
| 153 | 172 |
| 154 #endif // BASE_SCOPED_HANDLE_WIN_H_ | 173 #endif // BASE_SCOPED_HANDLE_WIN_H_ |
| OLD | NEW |