Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/base/src/shm.rs
5394 views
1
// Copyright 2020 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
use std::ffi::CStr;
6
use std::ffi::CString;
7
8
use libc::EINVAL;
9
use serde::Deserialize;
10
use serde::Serialize;
11
12
use crate::descriptor::AsRawDescriptor;
13
use crate::descriptor::SafeDescriptor;
14
use crate::Error;
15
use crate::RawDescriptor;
16
use crate::Result;
17
18
/// A shared memory file descriptor and its size.
19
#[derive(Debug, Deserialize, Serialize)]
20
pub struct SharedMemory {
21
#[serde(with = "crate::with_as_descriptor")]
22
pub descriptor: SafeDescriptor,
23
pub size: u64,
24
}
25
26
pub(crate) trait PlatformSharedMemory {
27
fn new(debug_name: &CStr, size: u64) -> Result<SharedMemory>;
28
fn from_safe_descriptor(descriptor: SafeDescriptor, size: u64) -> Result<SharedMemory>;
29
}
30
31
impl SharedMemory {
32
/// Creates a new shared memory object of the given size.
33
///
34
/// |name| is purely for debugging purposes. It does not need to be unique, and it does
35
/// not affect any non-debugging related properties of the constructed shared memory.
36
pub fn new<T: Into<Vec<u8>>>(debug_name: T, size: u64) -> Result<SharedMemory> {
37
let debug_name = CString::new(debug_name).map_err(|_| super::Error::new(EINVAL))?;
38
<SharedMemory as PlatformSharedMemory>::new(&debug_name, size)
39
}
40
41
/// Gets the size in bytes of the shared memory.
42
///
43
/// The size returned here does not reflect changes by other interfaces or users of the shared
44
/// memory file descriptor.
45
pub fn size(&self) -> u64 {
46
self.size
47
}
48
49
/// Creates a SharedMemory instance from a SafeDescriptor owning a reference to a
50
/// shared memory descriptor. Ownership of the underlying descriptor is transferred to the
51
/// new SharedMemory object.
52
pub fn from_safe_descriptor(descriptor: SafeDescriptor, size: u64) -> Result<SharedMemory> {
53
<SharedMemory as PlatformSharedMemory>::from_safe_descriptor(descriptor, size)
54
}
55
56
/// Clones the SharedMemory. The new SharedMemory will refer to the same
57
/// underlying object as the original.
58
pub fn try_clone(&self) -> Result<SharedMemory> {
59
Ok(SharedMemory {
60
descriptor: self.descriptor.try_clone()?,
61
size: self.size,
62
})
63
}
64
}
65
66
/// USE THIS CAUTIOUSLY. On Windows, the returned handle is not a file handle and cannot be used as
67
/// if it were one. It is a handle to a the associated file mapping object and should only be used
68
/// for memory-mapping the file view.
69
impl AsRawDescriptor for SharedMemory {
70
fn as_raw_descriptor(&self) -> RawDescriptor {
71
self.descriptor.as_raw_descriptor()
72
}
73
}
74
75
impl From<SharedMemory> for SafeDescriptor {
76
fn from(sm: SharedMemory) -> SafeDescriptor {
77
sm.descriptor
78
}
79
}
80
81
impl audio_streams::shm_streams::SharedMemory for SharedMemory {
82
type Error = Error;
83
84
fn anon(size: u64) -> Result<Self> {
85
SharedMemory::new("shm_streams", size)
86
}
87
88
fn size(&self) -> u64 {
89
self.size()
90
}
91
92
#[cfg(any(target_os = "android", target_os = "linux"))]
93
fn as_raw_fd(&self) -> RawDescriptor {
94
self.as_raw_descriptor()
95
}
96
}
97
98
#[cfg(test)]
99
mod tests {
100
use super::*;
101
102
#[test]
103
fn new_1024() {
104
let shm = SharedMemory::new("test", 1024).expect("failed to create shared memory");
105
assert_eq!(shm.size(), 1024);
106
}
107
108
#[test]
109
fn new_1028() {
110
let shm = SharedMemory::new("name", 1028).expect("failed to create shared memory");
111
assert_eq!(shm.size(), 1028);
112
}
113
114
#[test]
115
fn new_too_huge() {
116
SharedMemory::new("test", 0x8000_0000_0000_0000)
117
.expect_err("8 exabyte shared memory creation should fail");
118
}
119
}
120
121