File size: 1,772 Bytes
1d3f990
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//! Zero-copy IPC — Shared memory channel for cell communication

use anyhow::Result;
use std::sync::Arc;
use parking_lot::RwLock;

/// Zero-copy IPC channel
pub struct IpcChannel {
    channel_id: String,
    buffer: Arc<RwLock<Vec<u8>>>,
}

impl IpcChannel {
    pub fn new(channel_id: &str) -> Result<Self> {
        Ok(Self {
            channel_id: channel_id.to_string(),
            buffer: Arc::new(RwLock::new(Vec::with_capacity(65536))), // 64KB initial
        })
    }

    /// Send data via shared memory
    pub fn send(&self, data: &[u8]) -> Result<()> {
        let mut buf = self.buffer.write();
        buf.clear();
        buf.extend_from_slice(data);
        Ok(())
    }

    /// Receive data from shared memory
    pub fn recv(&self) -> Result<Vec<u8>> {
        let buf = self.buffer.read();
        Ok(buf.clone())
    }

    pub fn channel_id(&self) -> &str {
        &self.channel_id
    }

    pub fn clear(&self) {
        self.buffer.write().clear();
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_ipc_channel_creation() {
        let channel = IpcChannel::new("test").unwrap();
        assert_eq!(channel.channel_id(), "test");
    }

    #[test]
    fn test_send_recv() {
        let channel = IpcChannel::new("test").unwrap();
        let data = b"hello";
        channel.send(data).unwrap();

        let received = channel.recv().unwrap();
        assert_eq!(received, data);
    }

    #[test]
    fn test_clear() {
        let channel = IpcChannel::new("test").unwrap();
        channel.send(b"data").unwrap();
        channel.clear();

        let received = channel.recv().unwrap();
        assert!(received.is_empty());
    }
}