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_
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"
19 // TODO(rvargas): remove this with the rest of the verifier.
20 #if defined(COMPILER_MSVC)
21 // MSDN says to #include <intrin.h>, but that breaks the VS2005 build.
23 void* _ReturnAddress();
25 #define BASE_WIN_GET_CALLER _ReturnAddress()
26 #elif defined(COMPILER_GCC)
27 #define BASE_WIN_GET_CALLER __builtin_extract_return_addr(\\
28 __builtin_return_address(0))
31 // Generic wrapper for raw handles that takes care of closing handles
32 // automatically. The class interface follows the style of
33 // the ScopedStdioHandle class with a few additions:
34 // - IsValid() method can tolerate multiple invalid handle values such as NULL
35 // and INVALID_HANDLE_VALUE (-1) for Win32 handles.
36 // - Receive() method allows to receive a handle value from a function that
37 // takes a raw handle pointer only.
38 template <class Traits
, class Verifier
>
39 class GenericScopedHandle
{
40 MOVE_ONLY_TYPE_FOR_CPP_03(GenericScopedHandle
, RValue
)
43 typedef typename
Traits::Handle Handle
;
45 // Helper object to contain the effect of Receive() to the function that needs
46 // a pointer, and allow proper tracking of the handle.
49 explicit Receiver(GenericScopedHandle
* owner
)
50 : handle_(Traits::NullHandle()),
52 ~Receiver() { owner_
->Set(handle_
); }
54 operator Handle
*() { return &handle_
; }
58 GenericScopedHandle
* owner_
;
61 GenericScopedHandle() : handle_(Traits::NullHandle()) {}
63 explicit GenericScopedHandle(Handle handle
) : handle_(Traits::NullHandle()) {
67 // Move constructor for C++03 move emulation of this type.
68 GenericScopedHandle(RValue other
) : handle_(Traits::NullHandle()) {
69 Set(other
.object
->Take());
72 ~GenericScopedHandle() {
76 bool IsValid() const {
77 return Traits::IsHandleValid(handle_
);
80 // Move operator= for C++03 move emulation of this type.
81 GenericScopedHandle
& operator=(RValue other
) {
82 if (this != other
.object
) {
83 Set(other
.object
->Take());
88 void Set(Handle handle
) {
89 if (handle_
!= handle
) {
92 if (Traits::IsHandleValid(handle
)) {
94 Verifier::StartTracking(handle
, this, BASE_WIN_GET_CALLER
,
95 tracked_objects::GetProgramCounter());
104 operator Handle() const {
108 // This method is intended to be used with functions that require a pointer to
109 // a destination handle, like so:
110 // void CreateRequiredHandle(Handle* out_handle);
112 // CreateRequiredHandle(a.Receive());
114 DCHECK(!Traits::IsHandleValid(handle_
)) << "Handle must be NULL";
115 return Receiver(this);
118 // Transfers ownership away from this object.
120 Handle temp
= handle_
;
121 handle_
= Traits::NullHandle();
122 if (Traits::IsHandleValid(temp
)) {
123 Verifier::StopTracking(temp
, this, BASE_WIN_GET_CALLER
,
124 tracked_objects::GetProgramCounter());
129 // Explicitly closes the owned handle.
131 if (Traits::IsHandleValid(handle_
)) {
132 Verifier::StopTracking(handle_
, this, BASE_WIN_GET_CALLER
,
133 tracked_objects::GetProgramCounter());
135 if (!Traits::CloseHandle(handle_
))
138 handle_
= Traits::NullHandle();
146 #undef BASE_WIN_GET_CALLER
148 // The traits class for Win32 handles that can be closed via CloseHandle() API.
151 typedef HANDLE Handle
;
153 // Closes the handle.
154 static bool CloseHandle(HANDLE handle
) {
155 return ::CloseHandle(handle
) != FALSE
;
158 // Returns true if the handle value is valid.
159 static bool IsHandleValid(HANDLE handle
) {
160 return handle
!= NULL
&& handle
!= INVALID_HANDLE_VALUE
;
163 // Returns NULL handle value.
164 static HANDLE
NullHandle() {
169 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits
);
172 // Do-nothing verifier.
173 class DummyVerifierTraits
{
175 typedef HANDLE Handle
;
177 static void StartTracking(HANDLE handle
, const void* owner
,
178 const void* pc1
, const void* pc2
) {}
179 static void StopTracking(HANDLE handle
, const void* owner
,
180 const void* pc1
, const void* pc2
) {}
183 DISALLOW_IMPLICIT_CONSTRUCTORS(DummyVerifierTraits
);
186 // Performs actual run-time tracking.
187 class BASE_EXPORT VerifierTraits
{
189 typedef HANDLE Handle
;
191 static void StartTracking(HANDLE handle
, const void* owner
,
192 const void* pc1
, const void* pc2
);
193 static void StopTracking(HANDLE handle
, const void* owner
,
194 const void* pc1
, const void* pc2
);
197 DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits
);
200 typedef GenericScopedHandle
<HandleTraits
, VerifierTraits
> ScopedHandle
;
205 #endif // BASE_SCOPED_HANDLE_WIN_H_