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 | 7 |
| 8 #include <windows.h> | 8 #include <windows.h> |
| 9 | 9 |
| 10 #include "base/base_export.h" | 10 #include "base/base_export.h" |
| 11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/move.h" | |
| 14 | 15 |
| 15 namespace base { | 16 namespace base { |
| 16 namespace win { | 17 namespace win { |
| 17 | 18 |
| 18 // TODO(rvargas): remove this with the rest of the verifier. | 19 // TODO(rvargas): remove this with the rest of the verifier. |
| 19 #if defined(COMPILER_MSVC) | 20 #if defined(COMPILER_MSVC) |
| 20 // MSDN says to #include <intrin.h>, but that breaks the VS2005 build. | 21 // MSDN says to #include <intrin.h>, but that breaks the VS2005 build. |
| 21 extern "C" { | 22 extern "C" { |
| 22 void* _ReturnAddress(); | 23 void* _ReturnAddress(); |
| 23 } | 24 } |
| 24 #define BASE_WIN_GET_CALLER _ReturnAddress() | 25 #define BASE_WIN_GET_CALLER _ReturnAddress() |
| 25 #elif defined(COMPILER_GCC) | 26 #elif defined(COMPILER_GCC) |
| 26 #define BASE_WIN_GET_CALLER __builtin_extract_return_addr(\\ | 27 #define BASE_WIN_GET_CALLER __builtin_extract_return_addr(\\ |
| 27 __builtin_return_address(0)) | 28 __builtin_return_address(0)) |
| 28 #endif | 29 #endif |
| 29 | 30 |
| 30 // Generic wrapper for raw handles that takes care of closing handles | 31 // Generic wrapper for raw handles that takes care of closing handles |
| 31 // automatically. The class interface follows the style of | 32 // automatically. The class interface follows the style of |
| 32 // the ScopedStdioHandle class with a few additions: | 33 // the ScopedStdioHandle class with a few additions: |
| 33 // - IsValid() method can tolerate multiple invalid handle values such as NULL | 34 // - IsValid() method can tolerate multiple invalid handle values such as NULL |
| 34 // and INVALID_HANDLE_VALUE (-1) for Win32 handles. | 35 // and INVALID_HANDLE_VALUE (-1) for Win32 handles. |
| 35 // - 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 |
| 36 // takes a raw handle pointer only. | 37 // takes a raw handle pointer only. |
| 37 template <class Traits, class Verifier> | 38 template <class Traits, class Verifier> |
| 38 class GenericScopedHandle { | 39 class GenericScopedHandle { |
| 40 MOVE_ONLY_TYPE_FOR_CPP_03(GenericScopedHandle, RValue) | |
| 41 | |
| 39 public: | 42 public: |
| 40 typedef typename Traits::Handle Handle; | 43 typedef typename Traits::Handle Handle; |
| 41 | 44 |
| 42 GenericScopedHandle() : handle_(Traits::NullHandle()) {} | 45 GenericScopedHandle() : handle_(Traits::NullHandle()) {} |
| 43 | 46 |
| 44 explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) { | 47 explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) { |
| 45 Set(handle); | 48 Set(handle); |
| 46 } | 49 } |
| 47 | 50 |
| 51 // Move constructor for C++03 move emulation of this type. | |
| 52 GenericScopedHandle(RValue& other) : handle_(other.Take()) { | |
| 53 } | |
| 54 | |
| 48 ~GenericScopedHandle() { | 55 ~GenericScopedHandle() { |
| 49 Close(); | 56 Close(); |
| 50 } | 57 } |
| 51 | 58 |
| 52 bool IsValid() const { | 59 bool IsValid() const { |
| 53 return Traits::IsHandleValid(handle_); | 60 return Traits::IsHandleValid(handle_); |
| 54 } | 61 } |
| 55 | 62 |
| 63 // Move operator= for C++03 move emulation of this type. | |
| 64 GenericScopedHandle& operator=(RValue& other) { | |
| 65 // Swapping the handles helps to avoid problems while assigning a handle | |
|
jar (doing other things)
2012/08/08 01:42:52
The usual "trick" with dealing with self assignmen
alexeypa (please no reviews)
2012/08/08 01:59:30
src/base/move.h has a long explanation what it is
| |
| 66 // to itself. It is also cheap and matches base::scoped_ptr behavior. | |
| 67 Swap(other); | |
| 68 return *this; | |
| 69 } | |
| 70 | |
| 56 void Set(Handle handle) { | 71 void Set(Handle handle) { |
| 57 if (handle_ != handle) { | 72 if (handle_ != handle) { |
| 58 Close(); | 73 Close(); |
| 59 | 74 |
| 60 if (Traits::IsHandleValid(handle)) { | 75 if (Traits::IsHandleValid(handle)) { |
| 61 handle_ = handle; | 76 handle_ = handle; |
| 62 Verifier::StartTracking(handle, this, BASE_WIN_GET_CALLER, | 77 Verifier::StartTracking(handle, this, BASE_WIN_GET_CALLER, |
| 63 tracked_objects::GetProgramCounter()); | 78 tracked_objects::GetProgramCounter()); |
| 64 } | 79 } |
| 65 } | 80 } |
| 66 } | 81 } |
| 67 | 82 |
| 68 Handle Get() const { | 83 Handle Get() const { |
| 69 return handle_; | 84 return handle_; |
| 70 } | 85 } |
| 71 | 86 |
| 72 operator Handle() const { | 87 operator Handle() const { |
| 73 return handle_; | 88 return handle_; |
| 74 } | 89 } |
| 75 | 90 |
| 76 Handle* Receive() { | 91 Handle* Receive() { |
| 77 DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL"; | 92 DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL"; |
| 78 | 93 |
| 79 // We cannot track this case :(. Just tell the verifier about it. | 94 // We cannot track this case :(. Just tell the verifier about it. |
| 80 Verifier::StartTracking(INVALID_HANDLE_VALUE, this, BASE_WIN_GET_CALLER, | 95 Verifier::StartTracking(INVALID_HANDLE_VALUE, this, BASE_WIN_GET_CALLER, |
| 81 tracked_objects::GetProgramCounter()); | 96 tracked_objects::GetProgramCounter()); |
| 82 return &handle_; | 97 return &handle_; |
| 83 } | 98 } |
| 84 | 99 |
| 100 void Swap(GenericScopedHandle& other) { | |
| 101 Handle tmp = handle_; | |
| 102 handle_ = other.handle_; | |
| 103 other.handle_ = tmp; | |
| 104 } | |
| 105 | |
| 85 // Transfers ownership away from this object. | 106 // Transfers ownership away from this object. |
| 86 Handle Take() { | 107 Handle Take() { |
| 87 Handle temp = handle_; | 108 Handle temp = handle_; |
| 88 handle_ = Traits::NullHandle(); | 109 handle_ = Traits::NullHandle(); |
| 89 Verifier::StopTracking(temp, this, BASE_WIN_GET_CALLER, | 110 Verifier::StopTracking(temp, this, BASE_WIN_GET_CALLER, |
| 90 tracked_objects::GetProgramCounter()); | 111 tracked_objects::GetProgramCounter()); |
| 91 return temp; | 112 return temp; |
| 92 } | 113 } |
| 93 | 114 |
| 94 // Explicitly closes the owned handle. | 115 // Explicitly closes the owned handle. |
| 95 void Close() { | 116 void Close() { |
| 96 if (Traits::IsHandleValid(handle_)) { | 117 if (Traits::IsHandleValid(handle_)) { |
| 97 Verifier::StopTracking(handle_, this, BASE_WIN_GET_CALLER, | 118 Verifier::StopTracking(handle_, this, BASE_WIN_GET_CALLER, |
| 98 tracked_objects::GetProgramCounter()); | 119 tracked_objects::GetProgramCounter()); |
| 99 | 120 |
| 100 if (!Traits::CloseHandle(handle_)) | 121 if (!Traits::CloseHandle(handle_)) |
| 101 CHECK(false); | 122 CHECK(false); |
| 102 | 123 |
| 103 handle_ = Traits::NullHandle(); | 124 handle_ = Traits::NullHandle(); |
| 104 } | 125 } |
| 105 } | 126 } |
| 106 | 127 |
| 107 private: | 128 private: |
| 108 Handle handle_; | 129 Handle handle_; |
| 109 | |
| 110 DISALLOW_COPY_AND_ASSIGN(GenericScopedHandle); | |
| 111 }; | 130 }; |
| 112 | 131 |
| 113 #undef BASE_WIN_GET_CALLER | 132 #undef BASE_WIN_GET_CALLER |
| 114 | 133 |
| 115 // The traits class for Win32 handles that can be closed via CloseHandle() API. | 134 // The traits class for Win32 handles that can be closed via CloseHandle() API. |
| 116 class HandleTraits { | 135 class HandleTraits { |
| 117 public: | 136 public: |
| 118 typedef HANDLE Handle; | 137 typedef HANDLE Handle; |
| 119 | 138 |
| 120 // Closes the handle. | 139 // Closes the handle. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 private: | 182 private: |
| 164 DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits); | 183 DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits); |
| 165 }; | 184 }; |
| 166 | 185 |
| 167 typedef GenericScopedHandle<HandleTraits, VerifierTraits> ScopedHandle; | 186 typedef GenericScopedHandle<HandleTraits, VerifierTraits> ScopedHandle; |
| 168 | 187 |
| 169 } // namespace win | 188 } // namespace win |
| 170 } // namespace base | 189 } // namespace base |
| 171 | 190 |
| 172 #endif // BASE_SCOPED_HANDLE_WIN_H_ | 191 #endif // BASE_SCOPED_HANDLE_WIN_H_ |
| OLD | NEW |