@@ -1418,12 +1418,12 @@ pub fn page_size() -> uint {
14181418pub 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
14291429pub 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