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"
16 // TODO(rvargas): remove this with the rest of the verifier.
17 #if defined(COMPILER_MSVC)
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))
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
)
38 typedef typename
Traits::Handle Handle
;
40 GenericScopedHandle() : handle_(Traits::NullHandle()) {}
42 explicit GenericScopedHandle(Handle handle
) : handle_(Traits::NullHandle()) {
46 // Move constructor for C++03 move emulation of this type.
47 GenericScopedHandle(RValue other
) : handle_(Traits::NullHandle()) {
48 Set(other
.object
->Take());
51 ~GenericScopedHandle() {
55 bool IsValid() const {
56 return Traits::IsHandleValid(handle_
);
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());
67 void Set(Handle handle
) {
68 if (handle_
!= handle
) {
71 if (Traits::IsHandleValid(handle
)) {
73 Verifier::StartTracking(handle
, this, BASE_WIN_GET_CALLER
,
74 tracked_objects::GetProgramCounter());
83 operator Handle() const {
87 // Transfers ownership away from this object.
89 Handle temp
= handle_
;
90 handle_
= Traits::NullHandle();
91 if (Traits::IsHandleValid(temp
)) {
92 Verifier::StopTracking(temp
, this, BASE_WIN_GET_CALLER
,
93 tracked_objects::GetProgramCounter());
98 // Explicitly closes the owned handle.
100 if (Traits::IsHandleValid(handle_
)) {
101 Verifier::StopTracking(handle_
, this, BASE_WIN_GET_CALLER
,
102 tracked_objects::GetProgramCounter());
104 if (!Traits::CloseHandle(handle_
))
107 handle_
= Traits::NullHandle();
115 #undef BASE_WIN_GET_CALLER
117 // The traits class for Win32 handles that can be closed via CloseHandle() API.
120 typedef HANDLE Handle
;
122 // Closes the handle.
123 static bool CloseHandle(HANDLE handle
) {
124 return ::CloseHandle(handle
) != FALSE
;
127 // Returns true if the handle value is valid.
128 static bool IsHandleValid(HANDLE handle
) {
129 return handle
!= NULL
&& handle
!= INVALID_HANDLE_VALUE
;
132 // Returns NULL handle value.
133 static HANDLE
NullHandle() {
138 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits
);
141 // Do-nothing verifier.
142 class DummyVerifierTraits
{
144 typedef HANDLE Handle
;
146 static void StartTracking(HANDLE handle
, const void* owner
,
147 const void* pc1
, const void* pc2
) {}
148 static void StopTracking(HANDLE handle
, const void* owner
,
149 const void* pc1
, const void* pc2
) {}
152 DISALLOW_IMPLICIT_CONSTRUCTORS(DummyVerifierTraits
);
155 // Performs actual run-time tracking.
156 class BASE_EXPORT VerifierTraits
{
158 typedef HANDLE Handle
;
160 static void StartTracking(HANDLE handle
, const void* owner
,
161 const void* pc1
, const void* pc2
);
162 static void StopTracking(HANDLE handle
, const void* owner
,
163 const void* pc1
, const void* pc2
);
166 DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits
);
169 typedef GenericScopedHandle
<HandleTraits
, VerifierTraits
> ScopedHandle
;
174 #endif // BASE_SCOPED_HANDLE_WIN_H_