Fix crash in SpeechRecognizerImpl introduced in AudioParams refactor.
[chromium-blink-merge.git] / base / win / scoped_handle.h
blobd1eb1d688aeb5410c0cdf34ca45026f7fbd3a202
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.
5 #ifndef BASE_WIN_SCOPED_HANDLE_H_
6 #define BASE_WIN_SCOPED_HANDLE_H_
8 #include <windows.h>
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"
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
25 namespace base {
26 namespace win {
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 two additions:
31 // - IsValid() method can tolerate multiple invalid handle values such as NULL
32 // and INVALID_HANDLE_VALUE (-1) for Win32 handles.
33 // - Set() (and the constructors and assignment operators that call it)
34 // preserve the Windows LastError code. This ensures that GetLastError() can
35 // be called after stashing a handle in a GenericScopedHandle object. Doing
36 // this explicitly is necessary because of bug 528394 and VC++ 2015.
37 template <class Traits, class Verifier>
38 class GenericScopedHandle {
39 MOVE_ONLY_TYPE_FOR_CPP_03(GenericScopedHandle, RValue)
41 public:
42 typedef typename Traits::Handle Handle;
44 GenericScopedHandle() : handle_(Traits::NullHandle()) {}
46 explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) {
47 Set(handle);
50 // Move constructor for C++03 move emulation of this type.
51 GenericScopedHandle(RValue other) : handle_(Traits::NullHandle()) {
52 Set(other.object->Take());
55 ~GenericScopedHandle() {
56 Close();
59 bool IsValid() const {
60 return Traits::IsHandleValid(handle_);
63 // Move operator= for C++03 move emulation of this type.
64 GenericScopedHandle& operator=(RValue other) {
65 if (this != other.object) {
66 Set(other.object->Take());
68 return *this;
71 void Set(Handle handle) {
72 if (handle_ != handle) {
73 // Preserve old LastError to avoid bug 528394.
74 auto last_error = ::GetLastError();
75 Close();
77 if (Traits::IsHandleValid(handle)) {
78 handle_ = handle;
79 Verifier::StartTracking(handle, this, BASE_WIN_GET_CALLER,
80 tracked_objects::GetProgramCounter());
82 ::SetLastError(last_error);
86 Handle Get() const {
87 return handle_;
90 // Transfers ownership away from this object.
91 Handle Take() {
92 Handle temp = handle_;
93 handle_ = Traits::NullHandle();
94 if (Traits::IsHandleValid(temp)) {
95 Verifier::StopTracking(temp, this, BASE_WIN_GET_CALLER,
96 tracked_objects::GetProgramCounter());
98 return temp;
101 // Explicitly closes the owned handle.
102 void Close() {
103 if (Traits::IsHandleValid(handle_)) {
104 Verifier::StopTracking(handle_, this, BASE_WIN_GET_CALLER,
105 tracked_objects::GetProgramCounter());
107 Traits::CloseHandle(handle_);
108 handle_ = Traits::NullHandle();
112 private:
113 Handle handle_;
116 #undef BASE_WIN_GET_CALLER
118 // The traits class for Win32 handles that can be closed via CloseHandle() API.
119 class HandleTraits {
120 public:
121 typedef HANDLE Handle;
123 // Closes the handle.
124 static bool BASE_EXPORT CloseHandle(HANDLE handle);
126 // Returns true if the handle value is valid.
127 static bool IsHandleValid(HANDLE handle) {
128 return handle != NULL && handle != INVALID_HANDLE_VALUE;
131 // Returns NULL handle value.
132 static HANDLE NullHandle() {
133 return NULL;
136 private:
137 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits);
140 // Do-nothing verifier.
141 class DummyVerifierTraits {
142 public:
143 typedef HANDLE Handle;
145 static void StartTracking(HANDLE handle, const void* owner,
146 const void* pc1, const void* pc2) {}
147 static void StopTracking(HANDLE handle, const void* owner,
148 const void* pc1, const void* pc2) {}
150 private:
151 DISALLOW_IMPLICIT_CONSTRUCTORS(DummyVerifierTraits);
154 // Performs actual run-time tracking.
155 class BASE_EXPORT VerifierTraits {
156 public:
157 typedef HANDLE Handle;
159 static void StartTracking(HANDLE handle, const void* owner,
160 const void* pc1, const void* pc2);
161 static void StopTracking(HANDLE handle, const void* owner,
162 const void* pc1, const void* pc2);
164 private:
165 DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits);
168 typedef GenericScopedHandle<HandleTraits, VerifierTraits> ScopedHandle;
170 // This function may be called by the embedder to disable the use of
171 // VerifierTraits at runtime. It has no effect if DummyVerifierTraits is used
172 // for ScopedHandle.
173 void BASE_EXPORT DisableHandleVerifier();
175 // This should be called whenever the OS is closing a handle, if extended
176 // verification of improper handle closing is desired. If |handle| is being
177 // tracked by the handle verifier and ScopedHandle is not the one closing it,
178 // a CHECK is generated.
179 void BASE_EXPORT OnHandleBeingClosed(HANDLE handle);
181 } // namespace win
182 } // namespace base
184 #endif // BASE_WIN_SCOPED_HANDLE_H_