Skip to content

Commit efe832b

Browse files
committed
windows: fixed #82
1 parent 6226a95 commit efe832b

3 files changed

Lines changed: 102 additions & 128 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ nix = "0.23"
3535
libc = "0.2"
3636

3737
[target.'cfg(windows)'.dependencies]
38-
win-sys = "0"
38+
win-sys = "0.2"
3939

4040
[dev-dependencies]
4141
raw_sync = "0.1"

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use cfg_if::cfg_if;
1313
cfg_if! {
1414
if #[cfg(feature = "logging")] {
1515
pub use log;
16-
} else {
16+
} else {
1717
#[allow(unused_macros)]
1818
mod log {
1919
macro_rules! trace (($($tt:tt)*) => {{}});
@@ -259,7 +259,7 @@ impl Shmem {
259259
}
260260
/// Returns a raw pointer to the mapping
261261
pub fn as_ptr(&self) -> *mut u8 {
262-
self.mapping.map_ptr
262+
self.mapping.as_mut_ptr()
263263
}
264264
/// Returns mapping as a byte slice
265265
/// # Safety

src/windows.rs

Lines changed: 99 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,39 @@ use std::fs::{File, OpenOptions};
22
use std::io::ErrorKind;
33
use std::os::windows::{fs::OpenOptionsExt, io::AsRawHandle};
44
use std::path::PathBuf;
5-
use std::ptr::null_mut;
65

76
use crate::log::*;
87
use win_sys::*;
9-
use win_sys::Foundation::INVALID_HANDLE_VALUE;
108

119
use crate::ShmemError;
1210

1311
pub struct MapData {
1412
owner: bool,
1513

16-
///The handle to our open mapping
17-
map_handle: HANDLE,
14+
/// Pointer to the first byte of our mapping
15+
/// Keep this above `file_map` so it gets dropped first
16+
pub view: ViewOfFile,
17+
18+
/// The handle to our open mapping
19+
#[allow(dead_code)]
20+
file_map: FileMapping,
1821

1922
/// This file is used for shmem persistence. When an owner wants to drop the mapping,
2023
/// it opens the file with FILE_FLAG_DELETE_ON_CLOSE, renames the file and closes it.
2124
/// This makes it so future calls to open the old mapping will fail (as it was renamed) and
2225
/// deletes the renamed file once all handles have been closed.
26+
#[allow(dead_code)]
2327
persistent_file: Option<File>,
2428

2529
//Shared mapping uid
2630
pub unique_id: String,
2731
//Total size of the mapping
2832
pub map_size: usize,
29-
//Pointer to the first byte of our mapping
30-
pub map_ptr: *mut u8,
3133
}
3234
///Teardown UnmapViewOfFile and close CreateMapping handle
3335
impl Drop for MapData {
3436
///Takes care of properly closing the SharedMem
3537
fn drop(&mut self) {
36-
//Unmap memory from our process
37-
if !self.map_ptr.is_null() {
38-
trace!("UnmapViewOfFile(map_ptr:{:p})", self.map_ptr);
39-
let _ = UnmapViewOfFile(self.map_ptr as _);
40-
}
41-
42-
//Close our mapping
43-
if self.map_handle.0 != 0 {
44-
trace!("CloseHandle(map_handle:0x{:X})", self.map_handle.0);
45-
let _ = CloseHandle(self.map_handle);
46-
}
47-
4838
// Inspired by the boost implementation at
4939
// https://github.com/boostorg/interprocess/blob/140b50efb3281fa3898f3a4cf939cfbda174718f/include/boost/interprocess/detail/win32_api.hpp
5040
// Emulate POSIX behavior by
@@ -105,6 +95,9 @@ impl MapData {
10595
self.owner = is_owner;
10696
prev_val
10797
}
98+
pub fn as_mut_ptr(&self) -> *mut u8 {
99+
self.view.as_mut_ptr() as _
100+
}
108101
}
109102

110103
/// Returns the path to a temporary directory in which to store files backing the shared memory. If it
@@ -125,20 +118,13 @@ fn get_tmp_dir() -> Result<PathBuf, ShmemError> {
125118
}
126119
}
127120

128-
fn new_map(unique_id: &str, map_size: usize, create: bool) -> Result<MapData, ShmemError> {
129-
let mut f = None;
130-
let mut map_h = HANDLE(0);
131-
121+
fn new_map(unique_id: &str, map_size: usize, create: bool) -> Result<MapData, ShmemError> {
132122
// Create file to back the shared memory
133123
let mut file_path = get_tmp_dir()?;
134124
file_path.push(unique_id.trim_start_matches('/'));
135125
debug!(
136126
"{} persistent_file at {}",
137-
if create {
138-
"Creating"
139-
} else {
140-
"Openning"
141-
},
127+
if create { "Creating" } else { "Openning" },
142128
file_path.to_string_lossy()
143129
);
144130

@@ -153,120 +139,108 @@ fn new_map(unique_id: &str, map_size: usize, create: bool) -> Result<MapData, S
153139
opt.create(false);
154140
};
155141

156-
f = match opt.open(&file_path)
157-
{
158-
Ok(f) => Some(f),
159-
Err(e) if e.kind() == ErrorKind::AlreadyExists => return Err(ShmemError::MappingIdExists),
160-
Err(e) => return Err(
161-
if create {
162-
ShmemError::MapCreateFailed(e.raw_os_error().unwrap() as _)
163-
} else {
164-
debug!("Failed to open persistent posix mapping... Try to open raw shared memory by ID");
165-
// Allow openning memory mappings not managed by this crate
166-
// which do not create a file on disk for the mapping
167-
ShmemError::MapOpenFailed(e.raw_os_error().unwrap() as _)
168-
}),
169-
};
142+
let mut persistent_file = None;
143+
let map_h = match opt.open(&file_path) {
144+
Ok(f) => {
145+
//Create/open Mapping using persistent file
146+
debug!(
147+
"{} memory mapping",
148+
if create { "Creating" } else { "Openning" },
149+
);
150+
let high_size: u32 = ((map_size as u64 & 0xFFFF_FFFF_0000_0000_u64) >> 32) as u32;
151+
let low_size: u32 = (map_size as u64 & 0xFFFF_FFFF_u64) as u32;
152+
trace!(
153+
"CreateFileMapping({:?}, NULL, {:X}, {}, {}, '{}')",
154+
HANDLE(f.as_raw_handle() as _),
155+
PAGE_READWRITE.0,
156+
high_size,
157+
low_size,
158+
unique_id,
159+
);
170160

171-
// Start using MapData ASAP to rely on auto cleanup through Drop
172-
let mut new_map: MapData = MapData {
173-
owner: create,
174-
persistent_file: f,
175-
unique_id: String::from(unique_id),
176-
map_handle: map_h,
177-
map_size,
178-
map_ptr: null_mut(),
179-
};
180-
181-
if new_map.map_handle.0 == 0 {
182-
//Create Mapping
183-
debug!("{} memory mapping",
161+
match CreateFileMapping(
162+
HANDLE(f.as_raw_handle() as _),
163+
None,
164+
PAGE_READWRITE,
165+
high_size,
166+
low_size,
167+
unique_id,
168+
) {
169+
Ok(v) => {
170+
persistent_file = Some(f);
171+
v
172+
}
173+
Err(e) => {
174+
let err_code = e.win32_error().unwrap();
175+
return if err_code == ERROR_ALREADY_EXISTS {
176+
Err(ShmemError::MappingIdExists)
177+
} else {
178+
Err(if create {
179+
ShmemError::MapCreateFailed(err_code.0)
180+
} else {
181+
ShmemError::MapOpenFailed(err_code.0)
182+
})
183+
};
184+
}
185+
}
186+
}
187+
Err(e) if e.kind() == ErrorKind::AlreadyExists => return Err(ShmemError::MappingIdExists),
188+
Err(e) => {
184189
if create {
185-
"Creating"
186-
} else {
187-
"Openning"
188-
},
189-
);
190-
let high_size: u32 = ((map_size as u64 & 0xFFFF_FFFF_0000_0000_u64) >> 32) as u32;
191-
let low_size: u32 = (map_size as u64 & 0xFFFF_FFFF_u64) as u32;
192-
trace!(
193-
"CreateFileMappingW({:?}, NULL, {:X}, {}, {}, '{}') == 0x{:X}",
194-
new_map.persistent_file,
195-
PAGE_READWRITE.0,
196-
high_size,
197-
low_size,
198-
new_map.unique_id,
199-
new_map.map_handle.0
200-
);
190+
return Err(ShmemError::MapCreateFailed(e.raw_os_error().unwrap() as _));
191+
}
201192

202-
new_map.map_handle = match CreateFileMappingW(
203-
if let Some(h) = &new_map.persistent_file {
204-
HANDLE(h.as_raw_handle() as _)
205-
} else {
206-
INVALID_HANDLE_VALUE
207-
},
208-
None,
209-
PAGE_READWRITE,
210-
high_size,
211-
low_size,
212-
unique_id,
213-
) {
214-
Ok(v) => v,
215-
Err(e) => {
216-
let err_code = e.win32_error().unwrap();
217-
return if err_code == ERROR_ALREADY_EXISTS.0 {
218-
Err(ShmemError::MappingIdExists)
219-
} else {
220-
Err(if create {
221-
ShmemError::MapCreateFailed(err_code)
222-
} else {
223-
ShmemError::MapOpenFailed(err_code)
224-
})
225-
};
193+
// This may be a mapping that isnt managed by this crate
194+
// Try to open the mapping without any backing file
195+
trace!(
196+
"OpenFileMappingW({:?}, {}, '{}')",
197+
FILE_MAP_ALL_ACCESS,
198+
false,
199+
unique_id,
200+
);
201+
match OpenFileMapping(FILE_MAP_ALL_ACCESS, false, unique_id) {
202+
Ok(h) => h,
203+
Err(e) => {
204+
return Err(ShmemError::MapOpenFailed(e.win32_error().unwrap().0));
205+
}
226206
}
227-
};
207+
}
208+
};
209+
trace!("0x{:X}", map_h);
228210

229-
trace!(
230-
"CreateFileMappingW({:?}, NULL, {:X}, {}, {}, '{}') == 0x{:X}",
231-
new_map.persistent_file,
232-
PAGE_READWRITE.0,
233-
high_size,
234-
low_size,
235-
new_map.unique_id,
236-
new_map.map_handle.0
237-
);
238-
}
239-
240211
//Map mapping into address space
241212
debug!("Loading mapping into address space");
242213
trace!(
243214
"MapViewOfFile(0x{:X}, {:X}, 0, 0, 0)",
244-
new_map.map_handle.0,
215+
map_h,
245216
(FILE_MAP_READ | FILE_MAP_WRITE).0,
246217
);
247-
248-
new_map.map_ptr =
249-
match MapViewOfFile(new_map.map_handle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0) {
250-
Ok(v) => v as _,
251-
Err(e) => return Err(if create {
252-
ShmemError::MapCreateFailed(e.win32_error().unwrap())
218+
let map_ptr = match MapViewOfFile(map_h.as_handle(), FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0) {
219+
Ok(v) => v as _,
220+
Err(e) => {
221+
return Err(if create {
222+
ShmemError::MapCreateFailed(e.win32_error().unwrap().0)
253223
} else {
254-
ShmemError::MapOpenFailed(e.win32_error().unwrap())
255-
}),
256-
};
257-
258-
trace!(
259-
"MapViewOfFile(0x{:X}, {:X}, 0, 0, 0) == {:p}",
260-
new_map.map_handle.0,
261-
(FILE_MAP_READ | FILE_MAP_WRITE).0,
262-
new_map.map_ptr
263-
);
224+
ShmemError::MapOpenFailed(e.win32_error().unwrap().0)
225+
})
226+
}
227+
};
228+
trace!("\t{:p}", map_ptr);
229+
230+
let mut new_map = MapData {
231+
owner: create,
232+
file_map: map_h,
233+
persistent_file,
234+
unique_id: unique_id.to_string(),
235+
map_size: 0,
236+
view: map_ptr,
237+
};
264238

265239
if !create {
266240
//Get the real size of the openned mapping
267241
let mut info = MEMORY_BASIC_INFORMATION::default();
268-
if let Err(e) = VirtualQuery(new_map.map_ptr as _, &mut info) {
269-
return Err(ShmemError::UnknownOsError(e.win32_error().unwrap()));
242+
if let Err(e) = VirtualQuery(new_map.view.as_mut_ptr() as _, &mut info) {
243+
return Err(ShmemError::UnknownOsError(e.win32_error().unwrap().0));
270244
}
271245
new_map.map_size = info.RegionSize;
272246
}

0 commit comments

Comments
 (0)