1use std::mem::MaybeUninit;
2
3use evering::driver::OpId;
4use evering::op::{Cancellation, Completable};
5
6use crate::runtime::RuntimeHandle;
7use crate::shm::{ShmBox, ShmToken};
8
9#[derive(Debug)]
10pub struct Sqe {
11 pub id: OpId,
12 pub data: SqeData,
13}
14
15#[derive(Debug)]
16pub struct Rqe {
17 pub id: OpId,
18 pub data: RqeData,
19}
20
21#[derive(Debug)]
22pub enum SqeData {
23 Exit,
24 Ping {
25 ping: i32,
26 req: ShmToken<[u8]>,
27 resp: ShmToken<[MaybeUninit<u8>]>,
28 },
29}
30
31#[derive(Debug)]
32pub enum RqeData {
33 Exited,
34 Pong { pong: i32 },
35}
36
37struct Ping {
38 req: ShmBox<[u8]>,
39 resp: ShmBox<[MaybeUninit<u8>]>,
40}
41pub struct Pong {
42 pub pong: i32,
43 pub req: ShmBox<[u8]>,
44 pub resp: ShmBox<[u8]>,
45}
46unsafe impl Completable for Ping {
47 type Output = Pong;
48 type Driver = RuntimeHandle;
49 fn complete(self, _drv: &RuntimeHandle, payload: RqeData) -> Self::Output {
50 let RqeData::Pong { pong } = payload else {
51 unreachable!()
52 };
53 Pong {
54 pong,
55 req: self.req,
56 resp: unsafe { self.resp.assume_init() },
57 }
58 }
59 fn cancel(self, _drv: &RuntimeHandle) -> Cancellation {
60 Cancellation::recycle((self.req, self.resp))
61 }
62}
63
64pub async fn ping(ping: i32, req: ShmBox<[u8]>, resp: ShmBox<[MaybeUninit<u8>]>) -> Pong {
65 RuntimeHandle::submit(Ping { req, resp }, |id, p| Sqe {
66 id,
67 data: SqeData::Ping {
68 ping,
69 req: ShmBox::as_shm(&p.req),
70 resp: ShmBox::as_shm(&p.resp),
71 },
72 })
73 .await
74}
75
76struct Exit;
77unsafe impl Completable for Exit {
78 type Output = ();
79 type Driver = RuntimeHandle;
80 fn complete(self, _drv: &RuntimeHandle, payload: RqeData) -> Self::Output {
81 let RqeData::Exited = payload else {
82 unreachable!()
83 };
84 }
85 fn cancel(self, _drv: &RuntimeHandle) -> Cancellation {
86 Cancellation::noop()
87 }
88}
89
90pub async fn exit() {
91 RuntimeHandle::submit(Exit, |id, _| Sqe {
92 id,
93 data: SqeData::Exit,
94 })
95 .await
96}