llvm.org GIT mirror llvm / 1dd2ee7
Support/Windows: Cleanup scoped handles. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146362 91177308-0d34-0410-b5e6-96231b3b80d8 Michael J. Spencer 8 years ago
4 changed file(s) with 87 addition(s) and 66 deletion(s). Raw diff Collapse all Expand all
752752 if (ft == file_type::directory_file) {
753753 // This code would be a lot better with exceptions ;/.
754754 error_code ec;
755 for (directory_iterator i(path, ec), e; i != e; i.increment(ec)) {
755 directory_iterator i(path, ec);
756 if (ec) return ec;
757 for (directory_iterator e; i != e; i.increment(ec)) {
756758 if (ec) return ec;
757759 file_status st;
758760 if (error_code ec = i->status(st)) return ec;
1616 //===----------------------------------------------------------------------===//
1717
1818 #include "Windows.h"
19 #include
2019 #include
2120 #include
2221 #include
111110 return success;
112111 }
113112
114 // Forwarder for ScopedHandle.
115 BOOL WINAPI CryptReleaseContext(HCRYPTPROV Provider) {
116 return ::CryptReleaseContext(Provider, 0);
117 }
118
119 typedef ScopedHandle
120 BOOL (WINAPI*)(HCRYPTPROV), CryptReleaseContext>
121 ScopedCryptContext;
122113 bool is_separator(const wchar_t value) {
123114 switch (value) {
124115 case L'\\':
371362 if (error_code ec = UTF8ToUTF16(a, wide_a)) return ec;
372363 if (error_code ec = UTF8ToUTF16(b, wide_b)) return ec;
373364
374 AutoHandle HandleB(
365 ScopedFileHandle HandleB(
375366 ::CreateFileW(wide_b.begin(),
376367 0,
377368 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
380371 FILE_FLAG_BACKUP_SEMANTICS,
381372 0));
382373
383 AutoHandle HandleA(
374 ScopedFileHandle HandleA(
384375 ::CreateFileW(wide_a.begin(),
385376 0,
386377 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
390381 0));
391382
392383 // If both handles are invalid, it's an error.
393 if (HandleA == INVALID_HANDLE_VALUE &&
394 HandleB == INVALID_HANDLE_VALUE)
384 if (!HandleA && !HandleB)
395385 return windows_error(::GetLastError());
396386
397387 // If only one is invalid, it's false.
398 if (HandleA == INVALID_HANDLE_VALUE &&
399 HandleB == INVALID_HANDLE_VALUE) {
388 if (!HandleA || !HandleB) {
400389 result = false;
401390 return success;
402391 }
487476
488477 // Handle reparse points.
489478 if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
490 AutoHandle h(
479 ScopedFileHandle h(
491480 ::CreateFileW(path_utf16.begin(),
492481 0, // Attributes only.
493482 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
495484 OPEN_EXISTING,
496485 FILE_FLAG_BACKUP_SEMANTICS,
497486 0));
498 if (h == INVALID_HANDLE_VALUE)
487 if (!h)
499488 goto handle_status_error;
500489 }
501490
298298 Data_ = wpi;
299299
300300 // Make sure these get closed no matter what.
301 AutoHandle hThread(pi.hThread);
301 ScopedCommonHandle hThread(pi.hThread);
302302
303303 // Assign the process to a job if a memory limit is defined.
304 AutoHandle hJob(0);
304 ScopedJobHandle hJob;
305305 if (memoryLimit != 0) {
306306 hJob = CreateJobObject(0, 0);
307307 bool success = false;
308 if (hJob != 0) {
308 if (hJob) {
309309 JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
310310 memset(&jeli, 0, sizeof(jeli));
311311 jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY;
2525
2626 #include "llvm/Config/config.h" // Get build system configuration settings
2727 #include
28 #include
2829 #include
2930 #include
3031 #include
4041 return true;
4142 }
4243
43 class AutoHandle {
44 HANDLE handle;
44 template
45 class ScopedHandle {
46 typedef typename HandleTraits::handle_type handle_type;
47 handle_type Handle;
4548
49 ScopedHandle(const ScopedHandle &other); // = delete;
50 void operator=(const ScopedHandle &other); // = delete;
4651 public:
47 AutoHandle(HANDLE h) : handle(h) {}
52 ScopedHandle()
53 : Handle(HandleTraits::GetInvalid()) {}
4854
49 ~AutoHandle() {
50 if (handle)
51 CloseHandle(handle);
55 explicit ScopedHandle(handle_type h)
56 : Handle(h) {}
57
58 ~ScopedHandle() {
59 if (HandleTraits::IsValid(Handle))
60 HandleTraits::Close(Handle);
5261 }
5362
54 operator HANDLE() {
55 return handle;
63 handle_type take() {
64 handle_type t = Handle;
65 Handle = HandleTraits::GetInvalid();
66 return t;
5667 }
5768
58 AutoHandle &operator=(HANDLE h) {
59 handle = h;
69 ScopedHandle &operator=(handle_type h) {
70 if (HandleTraits::IsValid(Handle))
71 HandleTraits::Close(Handle);
72 Handle = h;
6073 return *this;
74 }
75
76 // True if Handle is valid.
77 operator bool() const {
78 return HandleTraits::IsValid(Handle) ? true : false;
79 }
80
81 operator handle_type() const {
82 return Handle;
6183 }
6284 };
6385
64 template
65 class DeleterType, DeleterType D>
66 class ScopedHandle {
67 HandleType Handle;
86 struct CommonHandleTraits {
87 typedef HANDLE handle_type;
6888
69 public:
70 ScopedHandle() : Handle(InvalidHandle) {}
71 ScopedHandle(HandleType handle) : Handle(handle) {}
72
73 ~ScopedHandle() {
74 if (Handle != HandleType(InvalidHandle))
75 D(Handle);
89 static handle_type GetInvalid() {
90 return INVALID_HANDLE_VALUE;
7691 }
7792
78 HandleType take() {
79 HandleType temp = Handle;
80 Handle = HandleType(InvalidHandle);
81 return temp;
93 static void Close(handle_type h) {
94 ::CloseHandle(h);
8295 }
8396
84 operator HandleType() const { return Handle; }
85
86 ScopedHandle &operator=(HandleType handle) {
87 Handle = handle;
88 return *this;
89 }
90
91 typedef void (*unspecified_bool_type)();
92 static void unspecified_bool_true() {}
93
94 // True if Handle is valid.
95 operator unspecified_bool_type() const {
96 return Handle == HandleType(InvalidHandle) ? 0 : unspecified_bool_true;
97 }
98
99 bool operator!() const {
100 return Handle == HandleType(InvalidHandle);
97 static bool IsValid(handle_type h) {
98 return h != GetInvalid();
10199 }
102100 };
103101
104 typedef ScopedHandle
105 BOOL (WINAPI*)(HANDLE), ::FindClose>
106 ScopedFindHandle;
102 struct JobHandleTraits : CommonHandleTraits {
103 static handle_type GetInvalid() {
104 return NULL;
105 }
106 };
107
108 struct CryptContextTraits : CommonHandleTraits {
109 typedef HCRYPTPROV handle_type;
110
111 static handle_type GetInvalid() {
112 return 0;
113 }
114
115 static void Close(handle_type h) {
116 ::CryptReleaseContext(h, 0);
117 }
118
119 static bool IsValid(handle_type h) {
120 return h != GetInvalid();
121 }
122 };
123
124 struct FindHandleTraits : CommonHandleTraits {
125 static void Close(handle_type h) {
126 ::FindClose(h);
127 }
128 };
129
130 struct FileHandleTraits : CommonHandleTraits {};
131
132 typedef ScopedHandle ScopedCommonHandle;
133 typedef ScopedHandle ScopedFileHandle;
134 typedef ScopedHandle ScopedCryptContext;
135 typedef ScopedHandle ScopedFindHandle;
136 typedef ScopedHandle ScopedJobHandle;
107137
108138 namespace llvm {
109139 template