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