mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-20 03:23:01 +02:00
Support/Windows: Cleanup scoped handles.
llvm-svn: 146362
This commit is contained in:
parent
b0340663fe
commit
88c9342c25
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
public:
|
||||
AutoHandle(HANDLE h) : handle(h) {}
|
||||
|
||||
~AutoHandle() {
|
||||
if (handle)
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
||||
operator HANDLE() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
AutoHandle &operator=(HANDLE h) {
|
||||
handle = h;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template <class HandleType, uintptr_t InvalidHandle,
|
||||
class DeleterType, DeleterType D>
|
||||
template <typename HandleTraits>
|
||||
class ScopedHandle {
|
||||
HandleType Handle;
|
||||
typedef typename HandleTraits::handle_type handle_type;
|
||||
handle_type Handle;
|
||||
|
||||
ScopedHandle(const ScopedHandle &other); // = delete;
|
||||
void operator=(const ScopedHandle &other); // = delete;
|
||||
public:
|
||||
ScopedHandle() : Handle(InvalidHandle) {}
|
||||
ScopedHandle(HandleType handle) : Handle(handle) {}
|
||||
ScopedHandle()
|
||||
: Handle(HandleTraits::GetInvalid()) {}
|
||||
|
||||
explicit ScopedHandle(handle_type h)
|
||||
: Handle(h) {}
|
||||
|
||||
~ScopedHandle() {
|
||||
if (Handle != HandleType(InvalidHandle))
|
||||
D(Handle);
|
||||
if (HandleTraits::IsValid(Handle))
|
||||
HandleTraits::Close(Handle);
|
||||
}
|
||||
|
||||
HandleType take() {
|
||||
HandleType temp = Handle;
|
||||
Handle = HandleType(InvalidHandle);
|
||||
return temp;
|
||||
handle_type take() {
|
||||
handle_type t = Handle;
|
||||
Handle = HandleTraits::GetInvalid();
|
||||
return t;
|
||||
}
|
||||
|
||||
operator HandleType() const { return Handle; }
|
||||
|
||||
ScopedHandle &operator=(HandleType handle) {
|
||||
Handle = handle;
|
||||
ScopedHandle &operator=(handle_type h) {
|
||||
if (HandleTraits::IsValid(Handle))
|
||||
HandleTraits::Close(Handle);
|
||||
Handle = h;
|
||||
return *this;
|
||||
}
|
||||
|
||||
typedef void (*unspecified_bool_type)();
|
||||
static void unspecified_bool_true() {}
|
||||
|
||||
// True if Handle is valid.
|
||||
operator unspecified_bool_type() const {
|
||||
return Handle == HandleType(InvalidHandle) ? 0 : unspecified_bool_true;
|
||||
operator bool() const {
|
||||
return HandleTraits::IsValid(Handle) ? true : false;
|
||||
}
|
||||
|
||||
bool operator!() const {
|
||||
return Handle == HandleType(InvalidHandle);
|
||||
operator handle_type() const {
|
||||
return Handle;
|
||||
}
|
||||
};
|
||||
|
||||
typedef ScopedHandle<HANDLE, uintptr_t(-1),
|
||||
BOOL (WINAPI*)(HANDLE), ::FindClose>
|
||||
ScopedFindHandle;
|
||||
struct CommonHandleTraits {
|
||||
typedef HANDLE handle_type;
|
||||
|
||||
static handle_type GetInvalid() {
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
static void Close(handle_type h) {
|
||||
::CloseHandle(h);
|
||||
}
|
||||
|
||||
static bool IsValid(handle_type h) {
|
||||
return h != GetInvalid();
|
||||
}
|
||||
};
|
||||
|
||||
struct JobHandleTraits : CommonHandleTraits {
|
||||
static handle_type GetInvalid() {
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
struct CryptContextTraits : CommonHandleTraits {
|
||||
typedef HCRYPTPROV handle_type;
|
||||
|
||||
static handle_type GetInvalid() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Close(handle_type h) {
|
||||
::CryptReleaseContext(h, 0);
|
||||
}
|
||||
|
||||
static bool IsValid(handle_type h) {
|
||||
return h != GetInvalid();
|
||||
}
|
||||
};
|
||||
|
||||
struct FindHandleTraits : CommonHandleTraits {
|
||||
static void Close(handle_type h) {
|
||||
::FindClose(h);
|
||||
}
|
||||
};
|
||||
|
||||
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>
|
||||
|
Loading…
Reference in New Issue
Block a user