1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 // Copyright 2018 Jacob Lifshay
5 use std::marker::PhantomData;
7 use std::ops::DerefMut;
8 use std::os::raw::c_int;
9 use std::ptr::null_mut;
13 pub struct SharedMemorySegment {
16 _phantom_data: PhantomData<*mut u8>,
19 unsafe impl Send for SharedMemorySegment {}
20 unsafe impl Sync for SharedMemorySegment {}
22 impl SharedMemorySegment {
23 pub unsafe fn new(id: c_int, size: usize) -> Self {
29 _phantom_data: PhantomData,
32 pub unsafe fn create_with_flags(size: usize, flags: c_int) -> Result<Self, errno::Errno> {
33 match libc::shmget(libc::IPC_PRIVATE, size, flags) {
34 -1 => Err(errno::errno()),
35 id => Ok(Self::new(id, size)),
38 pub fn create(size: usize) -> Result<Self, errno::Errno> {
39 unsafe { Self::create_with_flags(size, libc::IPC_CREAT | libc::IPC_EXCL | 0o666) }
41 pub fn map(&self) -> Result<MappedSharedMemorySegment, errno::Errno> {
43 let memory = libc::shmat(self.id, null_mut(), 0);
44 if memory == !0usize as *mut _ {
47 Ok(MappedSharedMemorySegment {
48 memory: memory as *mut u8,
56 impl Drop for SharedMemorySegment {
59 libc::shmctl(self.id, libc::IPC_RMID, null_mut());
65 pub struct MappedSharedMemorySegment {
70 impl MappedSharedMemorySegment {
71 unsafe fn get(&self) -> *mut [u8] {
72 slice::from_raw_parts_mut(self.memory, self.size)
76 unsafe impl Send for MappedSharedMemorySegment {}
77 unsafe impl Sync for MappedSharedMemorySegment {}
79 impl Deref for MappedSharedMemorySegment {
81 fn deref(&self) -> &[u8] {
82 unsafe { &*self.get() }
86 impl DerefMut for MappedSharedMemorySegment {
87 fn deref_mut(&mut self) -> &mut [u8] {
88 unsafe { &mut *self.get() }
92 impl Drop for MappedSharedMemorySegment {
95 libc::shmdt(self.memory as *const _);