Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: base/win/scoped_handle.h

Issue 9582045: Making GenericScopedHandle capable of handling handle types other than HANDLE. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixup. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 13
14 namespace base { 14 namespace base {
15 namespace win { 15 namespace win {
16 16
17 // Used so we always remember to close the handle. 17 // Generic wrapper for raw handles that takes care of closing handles
18 // The class interface matches that of ScopedStdioHandle in addition to an 18 // automatically. The class interface follows the style of
19 // IsValid() method since invalid handles on windows can be either NULL or 19 // the ScopedStdioHandle class with a few additions:
20 // INVALID_HANDLE_VALUE (-1). 20 // - IsValid() method can tolerate multiple invalid handle values such as NULL
21 // 21 // and INVALID_HANDLE_VALUE (-1) for Win32 handles.
22 // Example: 22 // - Receive() method allows to receive a handle value from a function that
23 // ScopedHandle hfile(CreateFile(...)); 23 // takes a raw handle pointer only.
24 // if (!hfile.Get())
25 // ...process error
26 // ReadFile(hfile.Get(), ...);
27 //
28 // To sqirrel the handle away somewhere else:
29 // secret_handle_ = hfile.Take();
30 //
31 // To explicitly close the handle:
32 // hfile.Close();
33 template <class Traits> 24 template <class Traits>
34 class GenericScopedHandle { 25 class GenericScopedHandle {
35 public: 26 public:
36 GenericScopedHandle() : handle_(NULL) { 27 typedef typename Traits::Handle Handle;
37 }
38 28
39 explicit GenericScopedHandle(HANDLE h) : handle_(NULL) { 29 GenericScopedHandle() : handle_(Traits::NullHandle()) {}
40 Set(h); 30
31 explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) {
32 Set(handle);
41 } 33 }
42 34
43 ~GenericScopedHandle() { 35 ~GenericScopedHandle() {
44 Close(); 36 Close();
45 } 37 }
46 38
47 // Use this instead of comparing to INVALID_HANDLE_VALUE to pick up our NULL
48 // usage for errors.
49 bool IsValid() const { 39 bool IsValid() const {
50 return handle_ != NULL; 40 return Traits::IsHandleValid(handle_);
51 } 41 }
52 42
53 void Set(HANDLE new_handle) { 43 void Set(Handle handle) {
54 Close(); 44 if (handle_ != handle) {
45 Close();
55 46
56 // Windows is inconsistent about invalid handles, so we always use NULL 47 if (Traits::IsHandleValid(handle)) {
57 if (new_handle != INVALID_HANDLE_VALUE) 48 handle_ = handle;
58 handle_ = new_handle; 49 }
50 }
59 } 51 }
60 52
61 HANDLE Get() { 53 Handle Get() const {
62 return handle_; 54 return handle_;
63 } 55 }
64 56
65 operator HANDLE() { return handle_; } 57 operator Handle() const {
58 return handle_;
59 }
66 60
67 HANDLE* Receive() { 61 Handle* Receive() {
68 DCHECK(!handle_) << "Handle must be NULL"; 62 DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL";
69 return &handle_; 63 return &handle_;
70 } 64 }
71 65
72 HANDLE Take() { 66 // Transfers ownership away from this object.
73 // transfers ownership away from this object 67 Handle Take() {
74 HANDLE h = handle_; 68 Handle temp = handle_;
75 handle_ = NULL; 69 handle_ = Traits::NullHandle();
76 return h; 70 return temp;
77 } 71 }
78 72
73 // Explicitly closes the owned handle.
79 void Close() { 74 void Close() {
80 if (handle_) { 75 if (Traits::IsHandleValid(handle_)) {
81 if (!Traits::CloseHandle(handle_)) { 76 if (!Traits::CloseHandle(handle_)) {
82 NOTREACHED(); 77 NOTREACHED();
83 } 78 }
84 handle_ = NULL; 79 handle_ = Traits::NullHandle();
85 } 80 }
86 } 81 }
87 82
88 private: 83 private:
89 HANDLE handle_; 84 Handle handle_;
85
90 DISALLOW_COPY_AND_ASSIGN(GenericScopedHandle); 86 DISALLOW_COPY_AND_ASSIGN(GenericScopedHandle);
91 }; 87 };
92 88
89 // The traits class for Win32 handles that can be closed via CloseHandle() API.
93 class HandleTraits { 90 class HandleTraits {
94 public: 91 public:
92 typedef HANDLE Handle;
93
94 // Closes the handle.
95 static bool CloseHandle(HANDLE handle) { 95 static bool CloseHandle(HANDLE handle) {
96 return ::CloseHandle(handle) != FALSE; 96 return ::CloseHandle(handle) != FALSE;
97 } 97 }
98
99 // Returns true if the handle value is valid.
100 static bool IsHandleValid(HANDLE handle) {
101 return handle != NULL && handle != INVALID_HANDLE_VALUE;
102 }
103
104 // Returns NULL handle value.
105 static HANDLE NullHandle() {
106 return NULL;
107 }
108
109 private:
110 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits);
98 }; 111 };
99 112
100 typedef GenericScopedHandle<HandleTraits> ScopedHandle; 113 typedef GenericScopedHandle<HandleTraits> ScopedHandle;
101 114
102 } // namespace win 115 } // namespace win
103 } // namespace base 116 } // namespace base
104 117
105 #endif // BASE_SCOPED_HANDLE_WIN_H_ 118 #endif // BASE_SCOPED_HANDLE_WIN_H_
OLDNEW
« no previous file with comments | « no previous file | chrome/service/cloud_print/print_system_win.cc » ('j') | chrome/service/cloud_print/print_system_win.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698