Skip to content

Commit 99345d8

Browse files
committed
Fixed MemoryMap on Windows.
1 parent 546e2ae commit 99345d8

File tree

1 file changed

+42
-25
lines changed

1 file changed

+42
-25
lines changed

src/libstd/os.rs

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,12 +1418,12 @@ pub fn page_size() -> uint {
14181418
pub fn page_size() -> uint {
14191419
#[fixed_stack_segment]; #[inline(never)];
14201420

1421-
unsafe {
1422-
let mut info = libc::SYSTEM_INFO::new();
1423-
libc::GetSystemInfo(&mut info);
1421+
unsafe {
1422+
let mut info = libc::SYSTEM_INFO::new();
1423+
libc::GetSystemInfo(&mut info);
14241424

1425-
return info.dwPageSize as uint;
1426-
}
1425+
return info.dwPageSize as uint;
1426+
}
14271427
}
14281428

14291429
pub struct MemoryMap {
@@ -1458,7 +1458,6 @@ pub enum MapError {
14581458
// Windows-specific errors
14591459
ErrUnsupProt,
14601460
ErrUnsupOffset,
1461-
ErrNeedRW,
14621461
ErrAlreadyExists,
14631462
ErrVirtualAlloc(uint),
14641463
ErrCreateFileMappingW(uint),
@@ -1477,7 +1476,6 @@ impl to_str::ToStr for MapError {
14771476
ErrUnknown(code) => fmt!("Unknown error=%?", code),
14781477
ErrUnsupProt => ~"Protection mode unsupported",
14791478
ErrUnsupOffset => ~"Offset in virtual memory mode is unsupported",
1480-
ErrNeedRW => ~"File mapping should be at least readable/writable",
14811479
ErrAlreadyExists => ~"File mapping for specified file already exists",
14821480
ErrVirtualAlloc(code) => fmt!("VirtualAlloc failure=%?", code),
14831481
ErrCreateFileMappingW(code) => fmt!("CreateFileMappingW failure=%?", code),
@@ -1542,6 +1540,10 @@ impl MemoryMap {
15421540
})
15431541
}
15441542
}
1543+
1544+
pub fn granularity() -> uint {
1545+
page_size()
1546+
}
15451547
}
15461548

15471549
#[cfg(unix)]
@@ -1617,21 +1619,21 @@ impl MemoryMap {
16171619
})
16181620
}
16191621
} else {
1620-
let dwDesiredAccess = match (readable, writable) {
1621-
(true, true) => libc::FILE_MAP_ALL_ACCESS,
1622-
(true, false) => libc::FILE_MAP_READ,
1623-
(false, true) => libc::FILE_MAP_WRITE,
1624-
_ => {
1625-
return Err(ErrNeedRW);
1626-
}
1622+
let dwDesiredAccess = match (executable, readable, writable) {
1623+
(false, true, false) => libc::FILE_MAP_READ,
1624+
(false, true, true) => libc::FILE_MAP_WRITE,
1625+
(true, true, false) => libc::FILE_MAP_READ | libc::FILE_MAP_EXECUTE,
1626+
(true, true, true) => libc::FILE_MAP_WRITE | libc::FILE_MAP_EXECUTE,
1627+
_ => return Err(ErrUnsupProt) // Actually, because of the check above,
1628+
// we should never get here.
16271629
};
16281630
unsafe {
16291631
let hFile = libc::get_osfhandle(fd) as HANDLE;
16301632
let mapping = libc::CreateFileMappingW(hFile,
16311633
ptr::mut_null(),
16321634
flProtect,
1633-
(len >> 32) as DWORD,
1634-
(len & 0xffff_ffff) as DWORD,
1635+
0,
1636+
0,
16351637
ptr::null());
16361638
if mapping == ptr::mut_null() {
16371639
return Err(ErrCreateFileMappingW(errno()));
@@ -1641,7 +1643,7 @@ impl MemoryMap {
16411643
}
16421644
let r = libc::MapViewOfFile(mapping,
16431645
dwDesiredAccess,
1644-
(offset >> 32) as DWORD,
1646+
((len as u64) >> 32) as DWORD,
16451647
(offset & 0xffff_ffff) as DWORD,
16461648
0);
16471649
match r as uint {
@@ -1655,6 +1657,19 @@ impl MemoryMap {
16551657
}
16561658
}
16571659
}
1660+
1661+
/// Granularity of MapAddr() and MapOffset() parameter values.
1662+
/// This may be greater than the value returned by page_size().
1663+
pub fn granularity() -> uint {
1664+
#[fixed_stack_segment]; #[inline(never)];
1665+
1666+
unsafe {
1667+
let mut info = libc::SYSTEM_INFO::new();
1668+
libc::GetSystemInfo(&mut info);
1669+
1670+
return info.dwAllocationGranularity as uint;
1671+
}
1672+
}
16581673
}
16591674
16601675
#[cfg(windows)]
@@ -1663,20 +1678,22 @@ impl Drop for MemoryMap {
16631678
#[fixed_stack_segment]; #[inline(never)];
16641679
16651680
use libc::types::os::arch::extra::{LPCVOID, HANDLE};
1681+
use libc::consts::os::extra::FALSE;
16661682
16671683
unsafe {
16681684
match self.kind {
1669-
MapVirtual => match libc::VirtualFree(self.data as *mut c_void,
1670-
self.len,
1671-
libc::MEM_RELEASE) {
1672-
0 => error!(fmt!("VirtualFree failed: %?", errno())),
1673-
_ => ()
1685+
MapVirtual => {
1686+
if libc::VirtualFree(self.data as *mut c_void,
1687+
self.len,
1688+
libc::MEM_RELEASE) == FALSE {
1689+
error!(fmt!("VirtualFree failed: %?", errno()));
1690+
}
16741691
},
16751692
MapFile(mapping) => {
1676-
if libc::UnmapViewOfFile(self.data as LPCVOID) != 0 {
1693+
if libc::UnmapViewOfFile(self.data as LPCVOID) == FALSE {
16771694
error!(fmt!("UnmapViewOfFile failed: %?", errno()));
16781695
}
1679-
if libc::CloseHandle(mapping as HANDLE) != 0 {
1696+
if libc::CloseHandle(mapping as HANDLE) == FALSE {
16801697
error!(fmt!("CloseHandle failed: %?", errno()));
16811698
}
16821699
}
@@ -2108,7 +2125,7 @@ mod tests {
21082125
}
21092126
21102127
let path = tmpdir().push("mmap_file.tmp");
2111-
let size = page_size() * 2;
2128+
let size = MemoryMap::granularity() * 2;
21122129
remove_file(&path);
21132130
21142131
let fd = unsafe {

0 commit comments

Comments
 (0)