use std::sync::{Arc, Mutex};
use std::collections::HashMap;
use crate::error::{Error, Result};
pub struct SharedMemoryRegion {
name: String,
buffer: Mutex<Vec<u8>>,
size: usize,
}
impl SharedMemoryRegion {
pub fn new(name: &str, size: usize) -> Self {
Self {
name: name.to_string(),
buffer: Mutex::new(vec![0; size]),
size,
}
}
pub fn read(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
let buffer = self.buffer.lock().unwrap();
if offset >= self.size {
return Err(Error::Communication {
channel: "shared_memory".to_string(),
reason: format!("Invalid offset: {}", offset),
instance_id: None,
});
}
let n = std::cmp::min(buf.len(), self.size - offset);
buf[..n].copy_from_slice(&buffer[offset..offset+n]);
Ok(n)
}
pub fn write(&self, offset: usize, data: &[u8]) -> Result<usize> {
let mut buffer = self.buffer.lock().unwrap();
if offset >= self.size {
return Err(Error::Communication {
channel: "shared_memory".to_string(),
reason: format!("Invalid offset: {}", offset),
instance_id: None,
});
}
let n = std::cmp::min(data.len(), self.size - offset);
buffer[offset..offset+n].copy_from_slice(&data[..n]);
Ok(n)
}
pub fn size(&self) -> usize {
self.size
}
pub fn name(&self) -> &str {
&self.name
}
}
pub struct SharedMemoryManager {
regions: Mutex<HashMap<String, Arc<SharedMemoryRegion>>>,
}
impl SharedMemoryManager {
pub fn new() -> Self {
Self {
regions: Mutex::new(HashMap::new()),
}
}
pub fn create_region(&self, name: &str, size: usize) -> Result<Arc<SharedMemoryRegion>> {
let mut regions = self.regions.lock().unwrap();
if regions.contains_key(name) {
return Err(Error::Communication {
channel: "shared_memory_manager".to_string(),
reason: format!("Region already exists: {}", name),
instance_id: None,
});
}
let region = Arc::new(SharedMemoryRegion::new(name, size));
regions.insert(name.to_string(), region.clone());
Ok(region)
}
pub fn get_region(&self, name: &str) -> Option<Arc<SharedMemoryRegion>> {
let regions = self.regions.lock().unwrap();
regions.get(name).cloned()
}
pub fn delete_region(&self, name: &str) -> Result<()> {
let mut regions = self.regions.lock().unwrap();
if regions.remove(name).is_none() {
return Err(Error::Communication {
channel: "shared_memory_manager".to_string(),
reason: format!("Region not found: {}", name),
instance_id: None,
});
}
Ok(())
}
pub fn list_regions(&self) -> Vec<String> {
let regions = self.regions.lock().unwrap();
regions.keys().cloned().collect()
}
}