Skip to main content

dope_runtime/process/
gate.rs

1use std::mem;
2
3use o3::base::marker::ThreadBound;
4
5use crate::process::{
6    failure::bus::{Event, Fault},
7    runtime::bus,
8};
9
10/// Single-use proof that one worker still holds its application gate closed.
11#[must_use]
12#[repr(transparent)]
13pub struct Closed<'run> {
14    tx: bus::Tx<'run>,
15    thread: ThreadBound,
16}
17
18/// Single-use proof that one worker has opened its application gate.
19#[must_use]
20#[repr(transparent)]
21pub struct Open<'run> {
22    tx: bus::Tx<'run>,
23    thread: ThreadBound,
24}
25
26impl<'run> Closed<'run> {
27    pub(in crate::process) const fn new(tx: bus::Tx<'run>) -> Self {
28        Self {
29            tx,
30            thread: ThreadBound::NEW,
31        }
32    }
33
34    pub fn open(self) -> Result<Open<'run>, Fault> {
35        let tx = self.tx;
36        tx.send(Event::Ready)?;
37        Ok(Open::new(tx))
38    }
39}
40
41impl<'run> Open<'run> {
42    const fn new(tx: bus::Tx<'run>) -> Self {
43        Self {
44            tx,
45            thread: ThreadBound::NEW,
46        }
47    }
48
49    pub fn finish(self) -> Result<(), Fault> {
50        self.tx.send(Event::Drain)
51    }
52}
53
54const _: () = {
55    assert!(mem::size_of::<Closed<'static>>() == mem::size_of::<bus::Tx<'static>>());
56    assert!(mem::align_of::<Closed<'static>>() == mem::align_of::<bus::Tx<'static>>());
57    assert!(mem::size_of::<Open<'static>>() == mem::size_of::<bus::Tx<'static>>());
58    assert!(mem::align_of::<Open<'static>>() == mem::align_of::<bus::Tx<'static>>());
59};