Skip to content

Commit 8443b2c

Browse files
Copilotyouknowonegithub-actions[bot]
authored
Add POSIX shared memory module for multiprocessing on Unix (#6498)
--------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 92acf33 commit 8443b2c

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

.cspell.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@
124124
"wasi",
125125
"zelf",
126126
// unix
127+
"posixshmem",
128+
"shm",
127129
"CLOEXEC",
128130
"codeset",
129131
"endgrent",

crates/stdlib/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ mod faulthandler;
5757
mod fcntl;
5858
#[cfg(not(target_arch = "wasm32"))]
5959
mod multiprocessing;
60+
#[cfg(all(unix, not(target_os = "redox"), not(target_os = "android")))]
61+
mod posixshmem;
6062
#[cfg(unix)]
6163
mod posixsubprocess;
6264
// libc is missing constants on redox
@@ -190,6 +192,10 @@ pub fn get_module_inits() -> impl Iterator<Item = (Cow<'static, str>, StdlibInit
190192
{
191193
"_posixsubprocess" => posixsubprocess::make_module,
192194
}
195+
#[cfg(all(unix, not(target_os = "redox"), not(target_os = "android")))]
196+
{
197+
"_posixshmem" => posixshmem::make_module,
198+
}
193199
#[cfg(any(unix, windows))]
194200
{
195201
"mmap" => mmap::make_module,

crates/stdlib/src/posixshmem.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#[cfg(all(unix, not(target_os = "redox"), not(target_os = "android")))]
2+
pub(crate) use _posixshmem::make_module;
3+
4+
#[cfg(all(unix, not(target_os = "redox"), not(target_os = "android")))]
5+
#[pymodule]
6+
mod _posixshmem {
7+
use std::ffi::CString;
8+
9+
use crate::{
10+
common::os::errno_io_error,
11+
vm::{
12+
PyResult, VirtualMachine, builtins::PyStrRef, convert::IntoPyException,
13+
function::OptionalArg,
14+
},
15+
};
16+
17+
#[pyfunction]
18+
fn shm_open(
19+
name: PyStrRef,
20+
flags: libc::c_int,
21+
mode: OptionalArg<libc::mode_t>,
22+
vm: &VirtualMachine,
23+
) -> PyResult<libc::c_int> {
24+
let name = CString::new(name.as_str()).map_err(|e| e.into_pyexception(vm))?;
25+
let mode: libc::c_uint = mode.unwrap_or(0o600) as _;
26+
#[cfg(target_os = "freebsd")]
27+
let mode = mode.try_into().unwrap();
28+
// SAFETY: `name` is a NUL-terminated string and `shm_open` does not write through it.
29+
let fd = unsafe { libc::shm_open(name.as_ptr(), flags, mode) };
30+
if fd == -1 {
31+
Err(errno_io_error().into_pyexception(vm))
32+
} else {
33+
Ok(fd)
34+
}
35+
}
36+
37+
#[pyfunction]
38+
fn shm_unlink(name: PyStrRef, vm: &VirtualMachine) -> PyResult<()> {
39+
let name = CString::new(name.as_str()).map_err(|e| e.into_pyexception(vm))?;
40+
// SAFETY: `name` is a valid NUL-terminated string and `shm_unlink` only reads it.
41+
let ret = unsafe { libc::shm_unlink(name.as_ptr()) };
42+
if ret == -1 {
43+
Err(errno_io_error().into_pyexception(vm))
44+
} else {
45+
Ok(())
46+
}
47+
}
48+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import os
2+
import sys
3+
4+
if os.name != "posix":
5+
sys.exit(0)
6+
7+
import _posixshmem
8+
9+
name = f"/rp_posixshmem_{os.getpid()}"
10+
fd = _posixshmem.shm_open(name, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0o600)
11+
os.close(fd)
12+
_posixshmem.shm_unlink(name)

0 commit comments

Comments
 (0)