Skip to content

Commit

Permalink
use winapi for non-stdlib Windows bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
euclio committed Jan 12, 2020
1 parent 1389494 commit 7b564c6
Show file tree
Hide file tree
Showing 18 changed files with 94 additions and 263 deletions.
6 changes: 6 additions & 0 deletions Cargo.lock
Expand Up @@ -201,6 +201,7 @@ dependencies = [
"serde_json",
"time",
"toml",
"winapi 0.3.8",
]

[[package]]
Expand Down Expand Up @@ -3491,6 +3492,7 @@ dependencies = [
"serialize",
"smallvec 1.0.0",
"stable_deref_trait",
"winapi 0.3.8",
]

[[package]]
Expand Down Expand Up @@ -3518,6 +3520,7 @@ dependencies = [
"rustc_target",
"serialize",
"syntax",
"winapi 0.3.8",
]

[[package]]
Expand All @@ -3537,6 +3540,7 @@ dependencies = [
"term_size",
"termcolor",
"unicode-width",
"winapi 0.3.8",
]

[[package]]
Expand Down Expand Up @@ -3647,6 +3651,7 @@ dependencies = [
"smallvec 1.0.0",
"syntax",
"tempfile",
"winapi 0.3.8",
]

[[package]]
Expand Down Expand Up @@ -3715,6 +3720,7 @@ dependencies = [
"smallvec 1.0.0",
"stable_deref_trait",
"syntax",
"winapi 0.3.8",
]

[[package]]
Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/Cargo.toml
Expand Up @@ -49,5 +49,9 @@ lazy_static = "1.3.0"
time = "0.1"
ignore = "0.4.10"

[target.'cfg(windows)'.dependencies.winapi]
version = "0.3"
features = ["fileapi", "ioapiset", "jobapi2", "handleapi", "winioctl"]

[dev-dependencies]
pretty_assertions = "0.5"
88 changes: 10 additions & 78 deletions src/bootstrap/job.rs
Expand Up @@ -35,84 +35,16 @@ use std::io;
use std::mem;
use std::ptr;

type HANDLE = *mut u8;
type BOOL = i32;
type DWORD = u32;
type LPHANDLE = *mut HANDLE;
type LPVOID = *mut u8;
type JOBOBJECTINFOCLASS = i32;
type SIZE_T = usize;
type LARGE_INTEGER = i64;
type UINT = u32;
type ULONG_PTR = usize;
type ULONGLONG = u64;

const FALSE: BOOL = 0;
const DUPLICATE_SAME_ACCESS: DWORD = 0x2;
const PROCESS_DUP_HANDLE: DWORD = 0x40;
const JobObjectExtendedLimitInformation: JOBOBJECTINFOCLASS = 9;
const JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: DWORD = 0x2000;
const JOB_OBJECT_LIMIT_PRIORITY_CLASS: DWORD = 0x00000020;
const SEM_FAILCRITICALERRORS: UINT = 0x0001;
const SEM_NOGPFAULTERRORBOX: UINT = 0x0002;
const BELOW_NORMAL_PRIORITY_CLASS: DWORD = 0x00004000;

extern "system" {
fn CreateJobObjectW(lpJobAttributes: *mut u8, lpName: *const u8) -> HANDLE;
fn CloseHandle(hObject: HANDLE) -> BOOL;
fn GetCurrentProcess() -> HANDLE;
fn OpenProcess(dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwProcessId: DWORD) -> HANDLE;
fn DuplicateHandle(
hSourceProcessHandle: HANDLE,
hSourceHandle: HANDLE,
hTargetProcessHandle: HANDLE,
lpTargetHandle: LPHANDLE,
dwDesiredAccess: DWORD,
bInheritHandle: BOOL,
dwOptions: DWORD,
) -> BOOL;
fn AssignProcessToJobObject(hJob: HANDLE, hProcess: HANDLE) -> BOOL;
fn SetInformationJobObject(
hJob: HANDLE,
JobObjectInformationClass: JOBOBJECTINFOCLASS,
lpJobObjectInformation: LPVOID,
cbJobObjectInformationLength: DWORD,
) -> BOOL;
fn SetErrorMode(mode: UINT) -> UINT;
}

#[repr(C)]
struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
BasicLimitInformation: JOBOBJECT_BASIC_LIMIT_INFORMATION,
IoInfo: IO_COUNTERS,
ProcessMemoryLimit: SIZE_T,
JobMemoryLimit: SIZE_T,
PeakProcessMemoryUsed: SIZE_T,
PeakJobMemoryUsed: SIZE_T,
}

#[repr(C)]
struct IO_COUNTERS {
ReadOperationCount: ULONGLONG,
WriteOperationCount: ULONGLONG,
OtherOperationCount: ULONGLONG,
ReadTransferCount: ULONGLONG,
WriteTransferCount: ULONGLONG,
OtherTransferCount: ULONGLONG,
}

#[repr(C)]
struct JOBOBJECT_BASIC_LIMIT_INFORMATION {
PerProcessUserTimeLimit: LARGE_INTEGER,
PerJobUserTimeLimit: LARGE_INTEGER,
LimitFlags: DWORD,
MinimumWorkingsetSize: SIZE_T,
MaximumWorkingsetSize: SIZE_T,
ActiveProcessLimit: DWORD,
Affinity: ULONG_PTR,
PriorityClass: DWORD,
SchedulingClass: DWORD,
}
use winapi::shared::minwindef::{DWORD, FALSE, LPVOID};
use winapi::um::errhandlingapi::SetErrorMode;
use winapi::um::handleapi::{CloseHandle, DuplicateHandle};
use winapi::um::jobapi2::{AssignProcessToJobObject, CreateJobObjectW, SetInformationJobObject};
use winapi::um::processthreadsapi::{GetCurrentProcess, OpenProcess};
use winapi::um::winbase::{BELOW_NORMAL_PRIORITY_CLASS, SEM_NOGPFAULTERRORBOX};
use winapi::um::winnt::{
JobObjectExtendedLimitInformation, DUPLICATE_SAME_ACCESS, JOBOBJECT_EXTENDED_LIMIT_INFORMATION,
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, JOB_OBJECT_LIMIT_PRIORITY_CLASS, PROCESS_DUP_HANDLE,
};

pub unsafe fn setup(build: &mut Build) {
// Enable the Windows Error Reporting dialog which msys disables,
Expand Down
62 changes: 13 additions & 49 deletions src/bootstrap/util.rs
Expand Up @@ -123,37 +123,24 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
// what can be found here:
//
// http://www.flexhex.com/docs/articles/hard-links.phtml
//
// Copied from std
#[cfg(windows)]
#[allow(nonstandard_style)]
fn symlink_dir_inner(target: &Path, junction: &Path) -> io::Result<()> {
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::ptr;

const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
const GENERIC_WRITE: DWORD = 0x40000000;
const OPEN_EXISTING: DWORD = 3;
const FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000;
const FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000;
const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;
const IO_REPARSE_TAG_MOUNT_POINT: DWORD = 0xa0000003;
const FILE_SHARE_DELETE: DWORD = 0x4;
const FILE_SHARE_READ: DWORD = 0x1;
const FILE_SHARE_WRITE: DWORD = 0x2;

type BOOL = i32;
type DWORD = u32;
type HANDLE = *mut u8;
type LPCWSTR = *const u16;
type LPDWORD = *mut DWORD;
type LPOVERLAPPED = *mut u8;
type LPSECURITY_ATTRIBUTES = *mut u8;
type LPVOID = *mut u8;
type WCHAR = u16;
type WORD = u16;

use winapi::shared::minwindef::{DWORD, WORD};
use winapi::um::fileapi::{CreateFileW, OPEN_EXISTING};
use winapi::um::handleapi::CloseHandle;
use winapi::um::ioapiset::DeviceIoControl;
use winapi::um::winbase::{FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT};
use winapi::um::winioctl::FSCTL_SET_REPARSE_POINT;
use winapi::um::winnt::{
FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_WRITE,
IO_REPARSE_TAG_MOUNT_POINT, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, WCHAR,
};

#[allow(non_snake_case)]
#[repr(C)]
struct REPARSE_MOUNTPOINT_DATA_BUFFER {
ReparseTag: DWORD,
Expand All @@ -165,29 +152,6 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
ReparseTarget: WCHAR,
}

extern "system" {
fn CreateFileW(
lpFileName: LPCWSTR,
dwDesiredAccess: DWORD,
dwShareMode: DWORD,
lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
dwCreationDisposition: DWORD,
dwFlagsAndAttributes: DWORD,
hTemplateFile: HANDLE,
) -> HANDLE;
fn DeviceIoControl(
hDevice: HANDLE,
dwIoControlCode: DWORD,
lpInBuffer: LPVOID,
nInBufferSize: DWORD,
lpOutBuffer: LPVOID,
nOutBufferSize: DWORD,
lpBytesReturned: LPDWORD,
lpOverlapped: LPOVERLAPPED,
) -> BOOL;
fn CloseHandle(hObject: HANDLE) -> BOOL;
}

fn to_u16s<S: AsRef<OsStr>>(s: S) -> io::Result<Vec<u16>> {
Ok(s.as_ref().encode_wide().chain(Some(0)).collect())
}
Expand All @@ -212,7 +176,7 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
ptr::null_mut(),
);

let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize];
let db = data.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER;
let buf = &mut (*db).ReparseTarget as *mut u16;
let mut i = 0;
Expand Down
1 change: 0 additions & 1 deletion src/librustc/lib.rs
Expand Up @@ -34,7 +34,6 @@
#![feature(const_transmute)]
#![feature(core_intrinsics)]
#![feature(drain_filter)]
#![cfg_attr(windows, feature(libc))]
#![feature(never_type)]
#![feature(exhaustive_patterns)]
#![feature(overlapping_marker_traits)]
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_data_structures/Cargo.toml
Expand Up @@ -31,3 +31,6 @@ measureme = "0.7.1"
[dependencies.parking_lot]
version = "0.9"
features = ["nightly"]

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["fileapi", "psapi"] }
34 changes: 3 additions & 31 deletions src/librustc_data_structures/flock.rs
Expand Up @@ -87,39 +87,11 @@ cfg_if! {
} else if #[cfg(windows)] {
use std::mem;
use std::os::windows::prelude::*;
use std::os::windows::raw::HANDLE;
use std::fs::{File, OpenOptions};
use std::os::raw::{c_ulong, c_int};

type DWORD = c_ulong;
type BOOL = c_int;
type ULONG_PTR = usize;

type LPOVERLAPPED = *mut OVERLAPPED;
const LOCKFILE_EXCLUSIVE_LOCK: DWORD = 0x0000_0002;
const LOCKFILE_FAIL_IMMEDIATELY: DWORD = 0x0000_0001;

const FILE_SHARE_DELETE: DWORD = 0x4;
const FILE_SHARE_READ: DWORD = 0x1;
const FILE_SHARE_WRITE: DWORD = 0x2;

#[repr(C)]
struct OVERLAPPED {
Internal: ULONG_PTR,
InternalHigh: ULONG_PTR,
Offset: DWORD,
OffsetHigh: DWORD,
hEvent: HANDLE,
}

extern "system" {
fn LockFileEx(hFile: HANDLE,
dwFlags: DWORD,
dwReserved: DWORD,
nNumberOfBytesToLockLow: DWORD,
nNumberOfBytesToLockHigh: DWORD,
lpOverlapped: LPOVERLAPPED) -> BOOL;
}
use winapi::um::minwinbase::{OVERLAPPED, LOCKFILE_FAIL_IMMEDIATELY, LOCKFILE_EXCLUSIVE_LOCK};
use winapi::um::fileapi::LockFileEx;
use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE};

#[derive(Debug)]
pub struct Lock {
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_data_structures/lib.rs
Expand Up @@ -33,9 +33,6 @@ extern crate libc;
#[macro_use]
extern crate cfg_if;

#[cfg(windows)]
extern crate libc;

pub use rustc_serialize::hex::ToHex;

#[inline(never)]
Expand Down
46 changes: 13 additions & 33 deletions src/librustc_data_structures/profiling.rs
Expand Up @@ -569,39 +569,19 @@ fn get_resident() -> Option<usize> {

#[cfg(windows)]
fn get_resident() -> Option<usize> {
type BOOL = i32;
type DWORD = u32;
type HANDLE = *mut u8;
use libc::size_t;
#[repr(C)]
#[allow(non_snake_case)]
struct PROCESS_MEMORY_COUNTERS {
cb: DWORD,
PageFaultCount: DWORD,
PeakWorkingSetSize: size_t,
WorkingSetSize: size_t,
QuotaPeakPagedPoolUsage: size_t,
QuotaPagedPoolUsage: size_t,
QuotaPeakNonPagedPoolUsage: size_t,
QuotaNonPagedPoolUsage: size_t,
PagefileUsage: size_t,
PeakPagefileUsage: size_t,
}
#[allow(non_camel_case_types)]
type PPROCESS_MEMORY_COUNTERS = *mut PROCESS_MEMORY_COUNTERS;
#[link(name = "psapi")]
extern "system" {
fn GetCurrentProcess() -> HANDLE;
fn GetProcessMemoryInfo(
Process: HANDLE,
ppsmemCounters: PPROCESS_MEMORY_COUNTERS,
cb: DWORD,
) -> BOOL;
}
let mut pmc: PROCESS_MEMORY_COUNTERS = unsafe { std::mem::zeroed() };
pmc.cb = std::mem::size_of_val(&pmc) as DWORD;
match unsafe { GetProcessMemoryInfo(GetCurrentProcess(), &mut pmc, pmc.cb) } {
use std::mem::{self, MaybeUninit};
use winapi::shared::minwindef::DWORD;
use winapi::um::processthreadsapi::GetCurrentProcess;
use winapi::um::psapi::{GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS};

let mut pmc = MaybeUninit::<PROCESS_MEMORY_COUNTERS>::uninit();
match unsafe {
GetProcessMemoryInfo(GetCurrentProcess(), pmc.as_mut_ptr(), mem::size_of_val(&pmc) as DWORD)
} {
0 => None,
_ => Some(pmc.WorkingSetSize as usize),
_ => {
let pmc = unsafe { pmc.assume_init() };
Some(pmc.WorkingSetSize as usize)
}
}
}
3 changes: 3 additions & 0 deletions src/librustc_driver/Cargo.toml
Expand Up @@ -32,5 +32,8 @@ rustc_serialize = { path = "../libserialize", package = "serialize" }
syntax = { path = "../libsyntax" }
rustc_span = { path = "../librustc_span" }

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] }

[features]
llvm = ['rustc_interface/llvm']

0 comments on commit 7b564c6

Please sign in to comment.