| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef BASE_WIN_SCOPED_HANDLE_H_ | |
| 6 #define BASE_WIN_SCOPED_HANDLE_H_ | |
| 7 | |
| 8 #include <windows.h> | |
| 9 | |
| 10 #include "base/base_export.h" | |
| 11 #include "base/basictypes.h" | |
| 12 #include "base/location.h" | |
| 13 #include "base/logging.h" | |
| 14 #include "base/move.h" | |
| 15 | |
| 16 // TODO(rvargas): remove this with the rest of the verifier. | |
| 17 #if defined(COMPILER_MSVC) | |
| 18 #include <intrin.h> | |
| 19 #define BASE_WIN_GET_CALLER _ReturnAddress() | |
| 20 #elif defined(COMPILER_GCC) | |
| 21 #define BASE_WIN_GET_CALLER __builtin_extract_return_addr(\\ | |
| 22 __builtin_return_address(0)) | |
| 23 #endif | |
| 24 | |
| 25 namespace base { | |
| 26 namespace win { | |
| 27 | |
| 28 // Generic wrapper for raw handles that takes care of closing handles | |
| 29 // automatically. The class interface follows the style of | |
| 30 // the ScopedFILE class with one addition: | |
| 31 // - IsValid() method can tolerate multiple invalid handle values such as NULL | |
| 32 // and INVALID_HANDLE_VALUE (-1) for Win32 handles. | |
| 33 template <class Traits, class Verifier> | |
| 34 class GenericScopedHandle { | |
| 35 MOVE_ONLY_TYPE_FOR_CPP_03(GenericScopedHandle, RValue) | |
| 36 | |
| 37 public: | |
| 38 typedef typename Traits::Handle Handle; | |
| 39 | |
| 40 GenericScopedHandle() : handle_(Traits::NullHandle()) {} | |
| 41 | |
| 42 explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) { | |
| 43 Set(handle); | |
| 44 } | |
| 45 | |
| 46 // Move constructor for C++03 move emulation of this type. | |
| 47 GenericScopedHandle(RValue other) : handle_(Traits::NullHandle()) { | |
| 48 Set(other.object->Take()); | |
| 49 } | |
| 50 | |
| 51 ~GenericScopedHandle() { | |
| 52 Close(); | |
| 53 } | |
| 54 | |
| 55 bool IsValid() const { | |
| 56 return Traits::IsHandleValid(handle_); | |
| 57 } | |
| 58 | |
| 59 // Move operator= for C++03 move emulation of this type. | |
| 60 GenericScopedHandle& operator=(RValue other) { | |
| 61 if (this != other.object) { | |
| 62 Set(other.object->Take()); | |
| 63 } | |
| 64 return *this; | |
| 65 } | |
| 66 | |
| 67 void Set(Handle handle) { | |
| 68 if (handle_ != handle) { | |
| 69 Close(); | |
| 70 | |
| 71 if (Traits::IsHandleValid(handle)) { | |
| 72 handle_ = handle; | |
| 73 Verifier::StartTracking(handle, this, BASE_WIN_GET_CALLER, | |
| 74 tracked_objects::GetProgramCounter()); | |
| 75 } | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 Handle Get() const { | |
| 80 return handle_; | |
| 81 } | |
| 82 | |
| 83 // Transfers ownership away from this object. | |
| 84 Handle Take() { | |
| 85 Handle temp = handle_; | |
| 86 handle_ = Traits::NullHandle(); | |
| 87 if (Traits::IsHandleValid(temp)) { | |
| 88 Verifier::StopTracking(temp, this, BASE_WIN_GET_CALLER, | |
| 89 tracked_objects::GetProgramCounter()); | |
| 90 } | |
| 91 return temp; | |
| 92 } | |
| 93 | |
| 94 // Explicitly closes the owned handle. | |
| 95 void Close() { | |
| 96 if (Traits::IsHandleValid(handle_)) { | |
| 97 Verifier::StopTracking(handle_, this, BASE_WIN_GET_CALLER, | |
| 98 tracked_objects::GetProgramCounter()); | |
| 99 | |
| 100 Traits::CloseHandle(handle_); | |
| 101 handle_ = Traits::NullHandle(); | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 private: | |
| 106 Handle handle_; | |
| 107 }; | |
| 108 | |
| 109 #undef BASE_WIN_GET_CALLER | |
| 110 | |
| 111 // The traits class for Win32 handles that can be closed via CloseHandle() API. | |
| 112 class HandleTraits { | |
| 113 public: | |
| 114 typedef HANDLE Handle; | |
| 115 | |
| 116 // Closes the handle. | |
| 117 static bool BASE_EXPORT CloseHandle(HANDLE handle); | |
| 118 | |
| 119 // Returns true if the handle value is valid. | |
| 120 static bool IsHandleValid(HANDLE handle) { | |
| 121 return handle != NULL && handle != INVALID_HANDLE_VALUE; | |
| 122 } | |
| 123 | |
| 124 // Returns NULL handle value. | |
| 125 static HANDLE NullHandle() { | |
| 126 return NULL; | |
| 127 } | |
| 128 | |
| 129 private: | |
| 130 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits); | |
| 131 }; | |
| 132 | |
| 133 // Do-nothing verifier. | |
| 134 class DummyVerifierTraits { | |
| 135 public: | |
| 136 typedef HANDLE Handle; | |
| 137 | |
| 138 static void StartTracking(HANDLE handle, const void* owner, | |
| 139 const void* pc1, const void* pc2) {} | |
| 140 static void StopTracking(HANDLE handle, const void* owner, | |
| 141 const void* pc1, const void* pc2) {} | |
| 142 | |
| 143 private: | |
| 144 DISALLOW_IMPLICIT_CONSTRUCTORS(DummyVerifierTraits); | |
| 145 }; | |
| 146 | |
| 147 // Performs actual run-time tracking. | |
| 148 class BASE_EXPORT VerifierTraits { | |
| 149 public: | |
| 150 typedef HANDLE Handle; | |
| 151 | |
| 152 static void StartTracking(HANDLE handle, const void* owner, | |
| 153 const void* pc1, const void* pc2); | |
| 154 static void StopTracking(HANDLE handle, const void* owner, | |
| 155 const void* pc1, const void* pc2); | |
| 156 | |
| 157 private: | |
| 158 DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits); | |
| 159 }; | |
| 160 | |
| 161 typedef GenericScopedHandle<HandleTraits, VerifierTraits> ScopedHandle; | |
| 162 | |
| 163 // This function may be called by the embedder to disable the use of | |
| 164 // VerifierTraits at runtime. It has no effect if DummyVerifierTraits is used | |
| 165 // for ScopedHandle. | |
| 166 void BASE_EXPORT DisableHandleVerifier(); | |
| 167 | |
| 168 // This should be called whenever the OS is closing a handle, if extended | |
| 169 // verification of improper handle closing is desired. If |handle| is being | |
| 170 // tracked by the handle verifier and ScopedHandle is not the one closing it, | |
| 171 // a CHECK is generated. | |
| 172 void BASE_EXPORT OnHandleBeingClosed(HANDLE handle); | |
| 173 | |
| 174 } // namespace win | |
| 175 } // namespace base | |
| 176 | |
| 177 #endif // BASE_WIN_SCOPED_HANDLE_H_ | |
| OLD | NEW |