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 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <windows.h> | 9 #include <windows.h> |
10 | 10 |
11 #include "base/base_export.h" | |
11 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/location.h" | |
12 #include "base/logging.h" | 14 #include "base/logging.h" |
13 | 15 |
14 namespace base { | 16 namespace base { |
15 namespace win { | 17 namespace win { |
16 | 18 |
17 // Generic wrapper for raw handles that takes care of closing handles | 19 // Generic wrapper for raw handles that takes care of closing handles |
18 // automatically. The class interface follows the style of | 20 // automatically. The class interface follows the style of |
19 // the ScopedStdioHandle class with a few additions: | 21 // the ScopedStdioHandle class with a few additions: |
20 // - IsValid() method can tolerate multiple invalid handle values such as NULL | 22 // - IsValid() method can tolerate multiple invalid handle values such as NULL |
21 // and INVALID_HANDLE_VALUE (-1) for Win32 handles. | 23 // and INVALID_HANDLE_VALUE (-1) for Win32 handles. |
22 // - Receive() method allows to receive a handle value from a function that | 24 // - Receive() method allows to receive a handle value from a function that |
23 // takes a raw handle pointer only. | 25 // takes a raw handle pointer only. |
24 template <class Traits> | 26 template <class Traits, class Verifier> |
25 class GenericScopedHandle { | 27 class GenericScopedHandle { |
26 public: | 28 public: |
27 typedef typename Traits::Handle Handle; | 29 typedef typename Traits::Handle Handle; |
28 | 30 |
29 GenericScopedHandle() : handle_(Traits::NullHandle()) {} | 31 GenericScopedHandle() : handle_(Traits::NullHandle()) {} |
30 | 32 |
31 explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) { | 33 explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) { |
32 Set(handle); | 34 Set(handle); |
33 } | 35 } |
34 | 36 |
35 ~GenericScopedHandle() { | 37 ~GenericScopedHandle() { |
36 Close(); | 38 Close(); |
37 } | 39 } |
38 | 40 |
39 bool IsValid() const { | 41 bool IsValid() const { |
40 return Traits::IsHandleValid(handle_); | 42 return Traits::IsHandleValid(handle_); |
41 } | 43 } |
42 | 44 |
43 void Set(Handle handle) { | 45 void Set(Handle handle) { |
44 if (handle_ != handle) { | 46 if (handle_ != handle) { |
45 Close(); | 47 Close(); |
46 | 48 |
47 if (Traits::IsHandleValid(handle)) { | 49 if (Traits::IsHandleValid(handle)) { |
48 handle_ = handle; | 50 handle_ = handle; |
51 Verifier::StartTracking(handle, this, | |
52 tracked_objects::GetProgramCounter()); | |
49 } | 53 } |
50 } | 54 } |
51 } | 55 } |
52 | 56 |
53 Handle Get() const { | 57 Handle Get() const { |
54 return handle_; | 58 return handle_; |
55 } | 59 } |
56 | 60 |
57 operator Handle() const { | 61 operator Handle() const { |
58 return handle_; | 62 return handle_; |
59 } | 63 } |
60 | 64 |
61 Handle* Receive() { | 65 Handle* Receive() { |
62 DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL"; | 66 DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL"; |
67 | |
68 // We cannot track this case :(. Just tell the verifier about it. | |
alexeypa (please no reviews)
2012/05/30 20:19:30
This is one of the most common ways of initializin
rvargas (doing something else)
2012/05/30 21:39:01
That is both unfortunate and surprising (given tha
| |
69 Verifier::StartTracking(INVALID_HANDLE_VALUE, this, | |
70 tracked_objects::GetProgramCounter()); | |
63 return &handle_; | 71 return &handle_; |
64 } | 72 } |
65 | 73 |
66 // Transfers ownership away from this object. | 74 // Transfers ownership away from this object. |
67 Handle Take() { | 75 Handle Take() { |
68 Handle temp = handle_; | 76 Handle temp = handle_; |
69 handle_ = Traits::NullHandle(); | 77 handle_ = Traits::NullHandle(); |
78 Verifier::StopTracking(temp, this, tracked_objects::GetProgramCounter()); | |
70 return temp; | 79 return temp; |
71 } | 80 } |
72 | 81 |
73 // Explicitly closes the owned handle. | 82 // Explicitly closes the owned handle. |
74 void Close() { | 83 void Close() { |
75 if (Traits::IsHandleValid(handle_)) { | 84 if (Traits::IsHandleValid(handle_)) { |
76 if (!Traits::CloseHandle(handle_)) { | 85 if (!Traits::CloseHandle(handle_)) { |
77 CHECK(false); | 86 CHECK(false); |
78 } | 87 } |
88 Verifier::StopTracking(handle_, this, | |
89 tracked_objects::GetProgramCounter()); | |
79 handle_ = Traits::NullHandle(); | 90 handle_ = Traits::NullHandle(); |
80 } | 91 } |
81 } | 92 } |
82 | 93 |
83 private: | 94 private: |
84 Handle handle_; | 95 Handle handle_; |
85 | 96 |
86 DISALLOW_COPY_AND_ASSIGN(GenericScopedHandle); | 97 DISALLOW_COPY_AND_ASSIGN(GenericScopedHandle); |
87 }; | 98 }; |
88 | 99 |
(...skipping 14 matching lines...) Expand all Loading... | |
103 | 114 |
104 // Returns NULL handle value. | 115 // Returns NULL handle value. |
105 static HANDLE NullHandle() { | 116 static HANDLE NullHandle() { |
106 return NULL; | 117 return NULL; |
107 } | 118 } |
108 | 119 |
109 private: | 120 private: |
110 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits); | 121 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits); |
111 }; | 122 }; |
112 | 123 |
113 typedef GenericScopedHandle<HandleTraits> ScopedHandle; | 124 // Do-nothing verifier. |
125 class DummyVerifierTraits { | |
126 public: | |
127 typedef HANDLE Handle; | |
128 | |
129 static void StartTracking(HANDLE handle, const void* owner, const void* pc) {} | |
130 static void StopTracking(HANDLE handle, const void* owner, const void* pc) {} | |
131 | |
132 private: | |
133 DISALLOW_IMPLICIT_CONSTRUCTORS(DummyVerifierTraits); | |
134 }; | |
135 | |
136 // Performs actual run-time tracking. | |
137 class BASE_EXPORT VerifierTraits { | |
138 public: | |
139 typedef HANDLE Handle; | |
140 | |
141 static void StartTracking(HANDLE handle, const void* owner, const void* pc); | |
142 static void StopTracking(HANDLE handle, const void* owner, const void* pc); | |
143 | |
144 private: | |
145 DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits); | |
146 }; | |
147 | |
148 typedef GenericScopedHandle<HandleTraits, DummyVerifierTraits> ScopedHandle; | |
114 | 149 |
115 } // namespace win | 150 } // namespace win |
116 } // namespace base | 151 } // namespace base |
117 | 152 |
118 #endif // BASE_SCOPED_HANDLE_WIN_H_ | 153 #endif // BASE_SCOPED_HANDLE_WIN_H_ |
OLD | NEW |