Stop linking tcmalloc into shared library components.
[chromium-blink-merge.git] / base / win / scoped_handle.h
blobd236a70beb4280316ece32a89b820ee38e86094e
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 namespace base {
17 namespace win {
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.
22 extern "C" {
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))
29 #endif
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)
42 public:
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.
47 class Receiver {
48 public:
49 explicit Receiver(GenericScopedHandle* owner)
50 : handle_(Traits::NullHandle()),
51 owner_(owner) {}
52 ~Receiver() { owner_->Set(handle_); }
54 operator Handle*() { return &handle_; }
56 private:
57 Handle handle_;
58 GenericScopedHandle* owner_;
61 GenericScopedHandle() : handle_(Traits::NullHandle()) {}
63 explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) {
64 Set(handle);
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() {
73 Close();
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());
85 return *this;
88 void Set(Handle handle) {
89 if (handle_ != handle) {
90 Close();
92 if (Traits::IsHandleValid(handle)) {
93 handle_ = handle;
94 Verifier::StartTracking(handle, this, BASE_WIN_GET_CALLER,
95 tracked_objects::GetProgramCounter());
100 Handle Get() const {
101 return handle_;
104 operator Handle() const {
105 return handle_;
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);
111 // ScopedHandle a;
112 // CreateRequiredHandle(a.Receive());
113 Receiver Receive() {
114 DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL";
115 return Receiver(this);
118 // Transfers ownership away from this object.
119 Handle Take() {
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());
126 return temp;
129 // Explicitly closes the owned handle.
130 void Close() {
131 if (Traits::IsHandleValid(handle_)) {
132 Verifier::StopTracking(handle_, this, BASE_WIN_GET_CALLER,
133 tracked_objects::GetProgramCounter());
135 if (!Traits::CloseHandle(handle_))
136 CHECK(false);
138 handle_ = Traits::NullHandle();
142 private:
143 Handle handle_;
146 #undef BASE_WIN_GET_CALLER
148 // The traits class for Win32 handles that can be closed via CloseHandle() API.
149 class HandleTraits {
150 public:
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() {
165 return NULL;
168 private:
169 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits);
172 // Do-nothing verifier.
173 class DummyVerifierTraits {
174 public:
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) {}
182 private:
183 DISALLOW_IMPLICIT_CONSTRUCTORS(DummyVerifierTraits);
186 // Performs actual run-time tracking.
187 class BASE_EXPORT VerifierTraits {
188 public:
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);
196 private:
197 DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits);
200 typedef GenericScopedHandle<HandleTraits, VerifierTraits> ScopedHandle;
202 } // namespace win
203 } // namespace base
205 #endif // BASE_SCOPED_HANDLE_WIN_H_