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