@@ -1418,12 +1418,12 @@ pub fn page_size() -> uint {
1418
1418
pub fn page_size ( ) -> uint {
1419
1419
#[ fixed_stack_segment] ; #[ inline( never) ] ;
1420
1420
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) ;
1424
1424
1425
- return info. dwPageSize as uint ;
1426
- }
1425
+ return info. dwPageSize as uint ;
1426
+ }
1427
1427
}
1428
1428
1429
1429
pub struct MemoryMap {
@@ -1458,7 +1458,6 @@ pub enum MapError {
1458
1458
// Windows-specific errors
1459
1459
ErrUnsupProt ,
1460
1460
ErrUnsupOffset ,
1461
- ErrNeedRW ,
1462
1461
ErrAlreadyExists ,
1463
1462
ErrVirtualAlloc ( uint ) ,
1464
1463
ErrCreateFileMappingW ( uint ) ,
@@ -1477,7 +1476,6 @@ impl to_str::ToStr for MapError {
1477
1476
ErrUnknown ( code) => fmt ! ( "Unknown error=%?" , code) ,
1478
1477
ErrUnsupProt => ~"Protection mode unsupported",
1479
1478
ErrUnsupOffset => ~"Offset in virtual memory mode is unsupported",
1480
- ErrNeedRW => ~"File mapping should be at least readable/writable",
1481
1479
ErrAlreadyExists => ~"File mapping for specified file already exists",
1482
1480
ErrVirtualAlloc ( code) => fmt ! ( "VirtualAlloc failure=%?" , code) ,
1483
1481
ErrCreateFileMappingW ( code) => fmt ! ( "CreateFileMappingW failure=%?" , code) ,
@@ -1542,6 +1540,10 @@ impl MemoryMap {
1542
1540
} )
1543
1541
}
1544
1542
}
1543
+
1544
+ pub fn granularity( ) -> uint {
1545
+ page_size( )
1546
+ }
1545
1547
}
1546
1548
1547
1549
#[ cfg( unix) ]
@@ -1617,21 +1619,21 @@ impl MemoryMap {
1617
1619
})
1618
1620
}
1619
1621
} 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.
1627
1629
};
1628
1630
unsafe {
1629
1631
let hFile = libc::get_osfhandle(fd) as HANDLE;
1630
1632
let mapping = libc::CreateFileMappingW(hFile,
1631
1633
ptr::mut_null(),
1632
1634
flProtect,
1633
- (len >> 32) as DWORD ,
1634
- (len & 0xffff_ffff) as DWORD ,
1635
+ 0 ,
1636
+ 0 ,
1635
1637
ptr::null());
1636
1638
if mapping == ptr::mut_null() {
1637
1639
return Err(ErrCreateFileMappingW(errno()));
@@ -1641,7 +1643,7 @@ impl MemoryMap {
1641
1643
}
1642
1644
let r = libc::MapViewOfFile(mapping,
1643
1645
dwDesiredAccess,
1644
- (offset >> 32) as DWORD,
1646
+ ((len as u64) >> 32) as DWORD,
1645
1647
(offset & 0xffff_ffff) as DWORD,
1646
1648
0);
1647
1649
match r as uint {
@@ -1655,6 +1657,19 @@ impl MemoryMap {
1655
1657
}
1656
1658
}
1657
1659
}
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
+ }
1658
1673
}
1659
1674
1660
1675
#[cfg(windows)]
@@ -1663,20 +1678,22 @@ impl Drop for MemoryMap {
1663
1678
#[fixed_stack_segment]; #[inline(never)];
1664
1679
1665
1680
use libc::types::os::arch::extra::{LPCVOID, HANDLE};
1681
+ use libc::consts::os::extra::FALSE;
1666
1682
1667
1683
unsafe {
1668
1684
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
+ }
1674
1691
},
1675
1692
MapFile(mapping) => {
1676
- if libc::UnmapViewOfFile(self.data as LPCVOID) != 0 {
1693
+ if libc::UnmapViewOfFile(self.data as LPCVOID) == FALSE {
1677
1694
error!(fmt!(" UnmapViewOfFile failed: %?", errno()));
1678
1695
}
1679
- if libc::CloseHandle(mapping as HANDLE) != 0 {
1696
+ if libc::CloseHandle(mapping as HANDLE) == FALSE {
1680
1697
error!(fmt!(" CloseHandle failed: %?", errno()));
1681
1698
}
1682
1699
}
@@ -2108,7 +2125,7 @@ mod tests {
2108
2125
}
2109
2126
2110
2127
let path = tmpdir().push(" mmap_file. tmp");
2111
- let size = page_size () * 2;
2128
+ let size = MemoryMap::granularity () * 2;
2112
2129
remove_file(&path);
2113
2130
2114
2131
let fd = unsafe {
0 commit comments