Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: installer/src/installer-lib/handle.h

Issue 6202981292703744: Whole installer (Closed)
Patch Set: Created June 24, 2014, 7:27 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /**
2 * \file handle.h The "install session" is the context for all custom installatio n behavior.
3 */
4
5 #ifndef HANDLE_H
6 #define HANDLE_H
7
8 #include "windows.h"
9 #include "msi.h"
10
11 //-------------------------------------------------------
12 // msi_handle
13 //-------------------------------------------------------
14 /**
15 * Disambiguation class holding an MSIHANDLE.
16 *
17 * We need constructors for Record that accept both handles and record counts.
18 * Since the underlying type of a handle is integral, without its own type these constructors are ambiguous.
19 */
20 class msi_handle
21 {
22 MSIHANDLE _handle ;
23
24 public:
25 /**
26 * Ordinary constructor is explicit to avoid inadvertent conversions.
27 */
28 explicit msi_handle( MSIHANDLE handle )
29 : _handle( handle )
30 {}
31
32 operator MSIHANDLE()
33 {
34 return _handle ;
35 }
36 } ;
37
38 //-------------------------------------------------------
39 // Handle Policies
40 //-------------------------------------------------------
41 /**
42 * Policy class that indicates that a raw handle may not be zero.
43 */
44 template< class T >
45 struct Disallow_Null
46 {
47 inline static bool prohibited_always() { return true ; }
48 inline static bool prohibited_from_outside() { return true ; }
49 } ;
50
51 /**
52 * Policy class that indicates that a raw handle may be zero only when constructe d internally.
53 */
54 template< class T >
55 struct Special_Null
56 {
57 inline static bool prohibited_always() { return false ; }
58 inline static bool prohibited_from_outside() { return true ; }
59 } ;
60
61 /**
62 * Policy class that indicates that a raw handle is permitted to be zero.
63 */
64 template< class T >
65 struct Allow_Null
66 {
67 inline static bool prohibited_always() { return false ; }
68 inline static bool prohibited_from_outside() { return false ; }
69 } ;
70
71 /**
72 * Policy class that does not close a handle at all.
73 */
74 template< class T >
75 class No_Destruction
76 {
77 public:
78 inline static void close( T handle ) {} ;
79 } ;
80
81 /**
82 * Policy class that closes an MSI handle when it goes out of scope.
83 */
84 template< class T >
85 class MSI_Generic_Destruction
86 {
87 public:
88 inline static void close( T handle )
89 {
90 MsiCloseHandle( handle ) ;
91 } ;
92 } ;
93
94 /**
95 * Policy class that closes a Windows handle when it goes out of scope.
96 */
97 template< class T >
98 class Windows_Generic_Destruction
99 {
100 public:
101 inline static void close( T handle )
102 {
103 CloseHandle( handle ) ;
104 } ;
105 } ;
106
107
108 //-------------------------------------------------------
109 // Handle
110 //-------------------------------------------------------
111 /**
112 * Raw handle is the base class for the generic handle.
113 *
114 * Raw handles always allow null, so that generic handles may allow or disallow t hem as they please.
115 */
116 template< class T >
117 class handle_raw
118 {
119 protected:
120 /**
121 * The underlying handle.
122 *
123 * This is the only data member of the class.
124 * Everything else is for life cycle and type conversion.
125 */
126 T _handle ;
127
128 /**
129 * Basic constructor is protected to cede creation policy entirely to subclasse s.
130 */
131 handle_raw( T _handle )
132 : _handle( _handle )
133 {}
134
135 public:
136 /**
137 * Conversion operator to underlying handle type.
138 */
139 operator T()
140 {
141 return _handle ;
142 }
143
144 /**
145 * Error thrown when initialize or assigning a null handle against policy.
146 *
147 * Note that this error is a logic_error, not a runtime error.
148 * If it's against policy for a handle to be null, it's an error for the caller to try to make it null.
149 * Policy enforcment here is not a substitute for good error handling by the ca ller.
150 * In many cases, the caller ought to be throwing windows_api_error.
151 */
152 struct null_handle_error
153 : public std::logic_error
154 {
155 null_handle_error()
156 : std::logic_error( "May not initialize with null handle" )
157 {}
158 } ;
159 } ;
160
161 /*
162 * Handle class
163 */
164 template<
165 class T,
166 template <class> class Null_Policy,
167 template <class> class Destruction_Policy = No_Destruction
168 >
169 class handle
170 : public handle_raw< T >
171 {
172 /**
173 * Copy constructor prohibited.
174 *
175 * This class represents an external resource and is responsible for its lifecy cle.
176 * As such, the semantics here require a one-to-one match between instances and resource.
177 * Copy construction violates these semantics.
178 *
179 * \par Implementation
180 * Currently, declared private and not defined.
181 * Add "= delete" for C++11.
182 */
183 handle( handle & ) ;
184
185 /**
186 * Copy assignment not implemented.
187 *
188 * It's not used anywhere yet.
189 *
190 * \par Implementation
191 * Currently, declared private and not defined.
192 */
193 handle operator=( const handle & ) ;
194
195 /**
196 * Validate initial handle values, both for construction and reinitialization a ssignment.
197 */
198 T validate_handle( T handle )
199 {
200 if ( Null_Policy< T >::prohibited_from_outside() && handle == 0 )
201 {
202 throw null_handle_error() ;
203 }
204 return handle ;
205 }
206
207 protected:
208 /**
209 * Tag class for null record constructor
210 */
211 class null_t {} ;
212
213 /**
214 * Null handle constructor initializes its handle to zero.
215 *
216 * The null record constructor avoids the ordinary check that an external handl e not be zero.
217 * It's declared protected so that it's not ordinarily visible.
218 * To use this constructor, derive from it and add a friend declaration.
219 */
220 handle( null_t )
221 : handle_raw( 0 )
222 {
223 if ( Null_Policy< T >::prohibited_always() )
224 {
225 throw null_handle_error() ;
226 }
227 }
228
229 public:
230 /**
231 * Ordinary constructor.
232 *
233 * A check for a non-zero handle compiles in conditionally based on the Null_Po licy.
234 */
235 handle( T handle )
236 : handle_raw( validate_handle( handle ) )
237 {}
238
239 /**
240 * Reinitialization Assignment.
241 *
242 * If we had C++11 move constructors, we wouldn't need this, since this acts ex actly as construct-plus-move would.
243 */
244 handle & operator=( T handle )
245 {
246 validate_handle( handle ) ;
247 this -> ~handle() ;
248 _handle = handle ;
249 return * this ;
250 }
251
252 /**
253 * Destructor
254 *
255 * The check for a non-zero handle compiles out conditionally based on Null_Pol icy.
256 * The specific function used to close the handle is given by the Destruction_P olicy.
257 */
258 ~handle()
259 {
260 if ( Null_Policy< T >::prohibited_always() || ( _handle != 0 ) ) {
261 Destruction_Policy< T >::close( _handle ) ;
262 }
263 }
264
265 /**
266 * Expose the underlying handle type.
267 */
268 typedef T handle_type ;
269 } ;
270
271 //-------------------------------------------------------
272 // Common instantiations of handle
273 //-------------------------------------------------------
274 typedef handle< HANDLE, Disallow_Null, Windows_Generic_Destruction > Windows_Han dle ;
275
276 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld