Support/Windows: Cleanup scoped handles.
authorMichael J. Spencer <bigcheesegs@gmail.com>
Mon, 12 Dec 2011 06:03:33 +0000 (06:03 +0000)
committerMichael J. Spencer <bigcheesegs@gmail.com>
Mon, 12 Dec 2011 06:03:33 +0000 (06:03 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146362 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/PathV2.cpp
lib/Support/Windows/PathV2.inc
lib/Support/Windows/Program.inc
lib/Support/Windows/Windows.h

index bebe442e24786add86f9f589112912bed179c350..0c145ab4f1c521f14535aaf2f776580d30ecd2d1 100644 (file)
@@ -753,7 +753,9 @@ error_code remove_all_r(StringRef path, file_type ft, uint32_t &count) {
   if (ft == file_type::directory_file) {
     // This code would be a lot better with exceptions ;/.
     error_code ec;
-    for (directory_iterator i(path, ec), e; i != e; i.increment(ec)) {
+    directory_iterator i(path, ec);
+    if (ec) return ec;
+    for (directory_iterator e; i != e; i.increment(ec)) {
       if (ec) return ec;
       file_status st;
       if (error_code ec = i->status(st)) return ec;
index 3872512e4faea7afb258495052d4d89ca3c36041..afb5533dc82eaf05f32a69a8429f180ca6e1606c 100644 (file)
@@ -17,7 +17,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "Windows.h"
-#include <wincrypt.h>
 #include <fcntl.h>
 #include <io.h>
 #include <sys/stat.h>
@@ -112,14 +111,6 @@ namespace {
     return success;
   }
 
-  // Forwarder for ScopedHandle.
-  BOOL WINAPI CryptReleaseContext(HCRYPTPROV Provider) {
-    return ::CryptReleaseContext(Provider, 0);
-  }
-
-  typedef ScopedHandle<HCRYPTPROV, uintptr_t(-1),
-                       BOOL (WINAPI*)(HCRYPTPROV), CryptReleaseContext>
-    ScopedCryptContext;
   bool is_separator(const wchar_t value) {
     switch (value) {
     case L'\\':
@@ -372,7 +363,7 @@ error_code equivalent(const Twine &A, const Twine &B, bool &result) {
   if (error_code ec = UTF8ToUTF16(a, wide_a)) return ec;
   if (error_code ec = UTF8ToUTF16(b, wide_b)) return ec;
 
-  AutoHandle HandleB(
+  ScopedFileHandle HandleB(
     ::CreateFileW(wide_b.begin(),
                   0,
                   FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
@@ -381,7 +372,7 @@ error_code equivalent(const Twine &A, const Twine &B, bool &result) {
                   FILE_FLAG_BACKUP_SEMANTICS,
                   0));
 
-  AutoHandle HandleA(
+  ScopedFileHandle HandleA(
     ::CreateFileW(wide_a.begin(),
                   0,
                   FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
@@ -391,13 +382,11 @@ error_code equivalent(const Twine &A, const Twine &B, bool &result) {
                   0));
 
   // If both handles are invalid, it's an error.
-  if (HandleA == INVALID_HANDLE_VALUE &&
-      HandleB == INVALID_HANDLE_VALUE)
+  if (!HandleA && !HandleB)
     return windows_error(::GetLastError());
 
   // If only one is invalid, it's false.
-  if (HandleA == INVALID_HANDLE_VALUE &&
-      HandleB == INVALID_HANDLE_VALUE) {
+  if (!HandleA || !HandleB) {
     result = false;
     return success;
   }
@@ -488,7 +477,7 @@ error_code status(const Twine &path, file_status &result) {
 
   // Handle reparse points.
   if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
-    AutoHandle h(
+    ScopedFileHandle h(
       ::CreateFileW(path_utf16.begin(),
                     0, // Attributes only.
                     FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
@@ -496,7 +485,7 @@ error_code status(const Twine &path, file_status &result) {
                     OPEN_EXISTING,
                     FILE_FLAG_BACKUP_SEMANTICS,
                     0));
-    if (h == INVALID_HANDLE_VALUE)
+    if (!h)
       goto handle_status_error;
   }
 
index 80cb7cc232d3c51ccf12bc1bf2e8c0492e3d1120..b328b3c29017bd85d144da79933ea158e02eb2bc 100644 (file)
@@ -299,14 +299,14 @@ Program::Execute(const Path& path,
   Data_ = wpi;
 
   // Make sure these get closed no matter what.
-  AutoHandle hThread(pi.hThread);
+  ScopedCommonHandle hThread(pi.hThread);
 
   // Assign the process to a job if a memory limit is defined.
-  AutoHandle hJob(0);
+  ScopedJobHandle hJob;
   if (memoryLimit != 0) {
     hJob = CreateJobObject(0, 0);
     bool success = false;
-    if (hJob != 0) {
+    if (hJob) {
       JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
       memset(&jeli, 0, sizeof(jeli));
       jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY;
index 67b6f015114fc0b5192cd1eec3cd33c6dd4e7499..5c1da0d617aa776132943a8042571c346eb8569e 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "llvm/Config/config.h" // Get build system configuration settings
 #include <windows.h>
+#include <wincrypt.h>
 #include <shlobj.h>
 #include <cassert>
 #include <string>
@@ -41,70 +42,99 @@ inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) {
   return true;
 }
 
-class AutoHandle {
-  HANDLE handle;
+template <typename HandleTraits>
+class ScopedHandle {
+  typedef typename HandleTraits::handle_type handle_type;
+  handle_type Handle;
 
+  ScopedHandle(const ScopedHandle &other); // = delete;
+  void operator=(const ScopedHandle &other); // = delete;
 public:
-  AutoHandle(HANDLE h) : handle(h) {}
+  ScopedHandle()
+    : Handle(HandleTraits::GetInvalid()) {}
+
+  explicit ScopedHandle(handle_type h)
+    : Handle(h) {}
 
-  ~AutoHandle() {
-    if (handle)
-      CloseHandle(handle);
+  ~ScopedHandle() {
+    if (HandleTraits::IsValid(Handle))
+      HandleTraits::Close(Handle);
   }
 
-  operator HANDLE() {
-    return handle;
+  handle_type take() {
+    handle_type t = Handle;
+    Handle = HandleTraits::GetInvalid();
+    return t;
   }
 
-  AutoHandle &operator=(HANDLE h) {
-    handle = h;
+  ScopedHandle &operator=(handle_type h) {
+    if (HandleTraits::IsValid(Handle))
+      HandleTraits::Close(Handle);
+    Handle = h;
     return *this;
   }
+
+  // True if Handle is valid.
+  operator bool() const {
+    return HandleTraits::IsValid(Handle) ? true : false;
+  }
+
+  operator handle_type() const {
+    return Handle;
+  }
 };
 
-template <class HandleType, uintptr_t InvalidHandle,
-          class DeleterType, DeleterType D>
-class ScopedHandle {
-  HandleType Handle;
+struct CommonHandleTraits {
+  typedef HANDLE handle_type;
 
-public:
-  ScopedHandle() : Handle(InvalidHandle) {}
-  ScopedHandle(HandleType handle) : Handle(handle) {}
+  static handle_type GetInvalid() {
+    return INVALID_HANDLE_VALUE;
+  }
 
-  ~ScopedHandle() {
-    if (Handle != HandleType(InvalidHandle))
-      D(Handle);
+  static void Close(handle_type h) {
+    ::CloseHandle(h);
   }
 
-  HandleType take() {
-    HandleType temp = Handle;
-    Handle = HandleType(InvalidHandle);
-    return temp;
+  static bool IsValid(handle_type h) {
+    return h != GetInvalid();
   }
+};
 
-  operator HandleType() const { return Handle; }
+struct JobHandleTraits : CommonHandleTraits {
+  static handle_type GetInvalid() {
+    return NULL;
+  }
+};
 
-  ScopedHandle &operator=(HandleType handle) {
-    Handle = handle;
-    return *this;
+struct CryptContextTraits : CommonHandleTraits {
+  typedef HCRYPTPROV handle_type;
+
+  static handle_type GetInvalid() {
+    return 0;
   }
 
-  typedef void (*unspecified_bool_type)();
-  static void unspecified_bool_true() {}
+  static void Close(handle_type h) {
+    ::CryptReleaseContext(h, 0);
+  }
 
-  // True if Handle is valid.
-  operator unspecified_bool_type() const {
-    return Handle == HandleType(InvalidHandle) ? 0 : unspecified_bool_true;
+  static bool IsValid(handle_type h) {
+    return h != GetInvalid();
   }
+};
 
-  bool operator!() const {
-    return Handle == HandleType(InvalidHandle);
+struct FindHandleTraits : CommonHandleTraits {
+  static void Close(handle_type h) {
+    ::FindClose(h);
   }
 };
 
-typedef ScopedHandle<HANDLE, uintptr_t(-1),
-                      BOOL (WINAPI*)(HANDLE), ::FindClose>
-  ScopedFindHandle;
+struct FileHandleTraits : CommonHandleTraits {};
+
+typedef ScopedHandle<CommonHandleTraits> ScopedCommonHandle;
+typedef ScopedHandle<FileHandleTraits>   ScopedFileHandle;
+typedef ScopedHandle<CryptContextTraits> ScopedCryptContext;
+typedef ScopedHandle<FindHandleTraits>   ScopedFindHandle;
+typedef ScopedHandle<JobHandleTraits>    ScopedJobHandle;
 
 namespace llvm {
 template <class T>