Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for read-only mapping #100

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,32 @@ cfg_if! {
}
}

#[derive(Clone, Default)]
#[derive(Clone)]
/// Struct used to configure different parameters before creating a shared memory mapping
pub struct ShmemConf {
owner: bool,
writable: bool,
os_id: Option<String>,
overwrite_flink: bool,
flink_path: Option<PathBuf>,
size: usize,
ext: os_impl::ShmemConfExt,
}

impl Default for ShmemConf {
fn default() -> Self {
Self {
owner: false,
writable: true,
os_id: None,
overwrite_flink: false,
flink_path: None,
size: Default::default(),
ext: Default::default(),
}
}
}

impl Drop for ShmemConf {
fn drop(&mut self) {
// Delete the flink if we are the owner of the mapping
Expand Down Expand Up @@ -100,6 +116,14 @@ impl ShmemConf {
self
}

/// Specifies whether the region should be writable by this process.
///
/// Enabled by default.
pub fn writable(mut self, writable: bool) -> Self {
self.writable = writable;
self
}

/// Create a new mapping using the current configuration
pub fn create(mut self) -> Result<Shmem, ShmemError> {
if self.size == 0 {
Expand All @@ -118,7 +142,7 @@ impl ShmemConf {
// Generate random ID until one works
loop {
let cur_id = format!("/shmem_{:X}", rand::random::<u64>());
match os_impl::create_mapping(&cur_id, self.size) {
match os_impl::create_mapping(&cur_id, self.size, self.writable) {
Err(ShmemError::MappingIdExists) => continue,
Ok(m) => break m,
Err(e) => {
Expand All @@ -127,7 +151,9 @@ impl ShmemConf {
};
}
}
Some(ref specific_id) => os_impl::create_mapping(specific_id, self.size)?,
Some(ref specific_id) => {
os_impl::create_mapping(specific_id, self.size, self.writable)?
}
};
debug!("Created shared memory mapping '{}'", mapping.unique_id);

Expand Down Expand Up @@ -204,7 +230,7 @@ impl ShmemConf {
flink_uid.as_str()
};

match os_impl::open_mapping(unique_id, self.size, &self.ext) {
match os_impl::open_mapping(unique_id, self.size, &self.ext, self.writable) {
Ok(m) => {
self.size = m.map_size;
self.owner = false;
Expand Down
45 changes: 30 additions & 15 deletions src/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ impl MapData {
}

/// Creates a mapping specified by the uid and size
pub fn create_mapping(unique_id: &str, map_size: usize) -> Result<MapData, ShmemError> {
pub fn create_mapping(
unique_id: &str,
map_size: usize,
writable: bool,
) -> Result<MapData, ShmemError> {
//Create shared memory file descriptor
debug!("Creating persistent mapping at {}", unique_id);

Expand Down Expand Up @@ -124,21 +128,26 @@ pub fn create_mapping(unique_id: &str, map_size: usize) -> Result<MapData, Shmem

//Put the mapping in our address space
debug!("Loading mapping into address space");
let access = if writable {
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE
} else {
ProtFlags::PROT_READ
};
new_map.map_ptr = match unsafe {
mmap(
None, //Desired addr
nz_map_size, //size of mapping
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, //Permissions on pages
MapFlags::MAP_SHARED, //What kind of mapping
new_map.map_fd, //fd
0, //Offset into fd
None, //Desired addr
nz_map_size, //size of mapping
access, //Permissions on pages
MapFlags::MAP_SHARED, //What kind of mapping
new_map.map_fd, //fd
0, //Offset into fd
)
} {
Ok(v) => {
trace!(
"mmap(NULL, {}, {:X}, {:X}, {}, 0) == {:p}",
new_map.map_size,
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
access,
MapFlags::MAP_SHARED,
new_map.map_fd,
v
Expand All @@ -156,6 +165,7 @@ pub fn open_mapping(
unique_id: &str,
_map_size: usize,
_ext: &ShmemConfExt,
writable: bool,
) -> Result<MapData, ShmemError> {
//Open shared memory
debug!("Openning persistent mapping at {}", unique_id);
Expand Down Expand Up @@ -195,21 +205,26 @@ pub fn open_mapping(

//Map memory into our address space
debug!("Loading mapping into address space");
let access = if writable {
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE
} else {
ProtFlags::PROT_READ
};
new_map.map_ptr = match unsafe {
mmap(
None, //Desired addr
nz_map_size, //size of mapping
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, //Permissions on pages
MapFlags::MAP_SHARED, //What kind of mapping
new_map.map_fd, //fd
0, //Offset into fd
None, //Desired addr
nz_map_size, //size of mapping
access, //Permissions on pages
MapFlags::MAP_SHARED, //What kind of mapping
new_map.map_fd, //fd
0, //Offset into fd
)
} {
Ok(v) => {
trace!(
"mmap(NULL, {}, {:X}, {:X}, {}, 0) == {:p}",
new_map.map_size,
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
access,
MapFlags::MAP_SHARED,
new_map.map_fd,
v
Expand Down
25 changes: 16 additions & 9 deletions src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ fn new_map(
mut map_size: usize,
create: bool,
allow_raw: bool,
writable: bool,
) -> Result<MapData, ShmemError> {
// Create file to back the shared memory
let mut file_path = get_tmp_dir()?;
Expand Down Expand Up @@ -230,12 +231,13 @@ fn new_map(

//Map mapping into address space
debug!("Loading mapping into address space");
trace!(
"MapViewOfFile(0x{:X}, {:X}, 0, 0, 0)",
map_h,
(FILE_MAP_READ | FILE_MAP_WRITE).0,
);
let map_ptr = match MapViewOfFile(map_h.as_handle(), FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0) {
let access = if writable {
FILE_MAP_READ | FILE_MAP_WRITE
} else {
FILE_MAP_READ
};
trace!("MapViewOfFile(0x{:X}, {:X}, 0, 0, 0)", map_h, access.0,);
let map_ptr = match MapViewOfFile(map_h.as_handle(), access, 0, 0, 0) {
Ok(v) => v,
Err(e) => {
return Err(if create {
Expand Down Expand Up @@ -267,15 +269,20 @@ fn new_map(
}

//Creates a mapping specified by the uid and size
pub fn create_mapping(unique_id: &str, map_size: usize) -> Result<MapData, ShmemError> {
new_map(unique_id, map_size, true, false)
pub fn create_mapping(
unique_id: &str,
map_size: usize,
writable: bool,
) -> Result<MapData, ShmemError> {
new_map(unique_id, map_size, true, false, writable)
}

//Opens an existing mapping specified by its uid
pub fn open_mapping(
unique_id: &str,
map_size: usize,
ext: &ShmemConfExt,
writable: bool,
) -> Result<MapData, ShmemError> {
new_map(unique_id, map_size, false, ext.allow_raw)
new_map(unique_id, map_size, false, ext.allow_raw, writable)
}