Files
@ 8ab15200d9a4
Branch filter:
Location: CSY/reowolf/src/runtime/retired/connector.rs - annotation
8ab15200d9a4
6.9 KiB
application/rls-services+xml
misc refactoring: (1) more thorough error handling, (2) more modular functions
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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 cc23d3cb40d3 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 cc23d3cb40d3 cc23d3cb40d3 cc23d3cb40d3 cc23d3cb40d3 cc23d3cb40d3 cc23d3cb40d3 0fb83f27a238 557148ec2325 cc23d3cb40d3 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 cc23d3cb40d3 cc23d3cb40d3 cc23d3cb40d3 1410a137843e 1410a137843e 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 cc23d3cb40d3 0fb83f27a238 06f259bf8031 06f259bf8031 06f259bf8031 0fb83f27a238 0fb83f27a238 0fb83f27a238 0fb83f27a238 0fb83f27a238 0fb83f27a238 0fb83f27a238 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 0fb83f27a238 06f259bf8031 06f259bf8031 557148ec2325 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 91c57e99c66e 91c57e99c66e 557148ec2325 91c57e99c66e 91c57e99c66e 91c57e99c66e 91c57e99c66e 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 dedf89df1602 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 c8c589cbcc4a dedf89df1602 06f259bf8031 06f259bf8031 dedf89df1602 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 dedf89df1602 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 c8c589cbcc4a dedf89df1602 06f259bf8031 06f259bf8031 dedf89df1602 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 1f2d007ac1cc 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 c8c589cbcc4a c8c589cbcc4a 06f259bf8031 c8c589cbcc4a c8c589cbcc4a 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 06f259bf8031 af5facdd41b1 ce6bcc0a0c26 02eb59c6fd66 06f259bf8031 06f259bf8031 | use crate::common::*;
use crate::runtime::{errors::*, *};
pub fn random_controller_id() -> ControllerId {
type Bytes8 = [u8; std::mem::size_of::<ControllerId>()];
let mut bytes = Bytes8::default();
getrandom::getrandom(&mut bytes).unwrap();
unsafe { std::mem::transmute::<Bytes8, ControllerId>(bytes) }
}
impl Default for Unconfigured {
fn default() -> Self {
let controller_id = random_controller_id();
Self { controller_id }
}
}
impl Default for Connector {
fn default() -> Self {
Self::Unconfigured(Unconfigured::default())
}
}
impl Connector {
/// Configure the Connector with the given Pdl description.
pub fn configure(&mut self, pdl: &[u8], main_component: &[u8]) -> Result<(), ConfigErr> {
use ConfigErr::*;
let controller_id = match self {
Connector::Configured(_) => return Err(AlreadyConfigured),
Connector::Connected(_) => return Err(AlreadyConnected),
Connector::Unconfigured(Unconfigured { controller_id }) => *controller_id,
};
let protocol_description = Arc::new(ProtocolD::parse(pdl).map_err(ParseErr)?);
let polarities = protocol_description.component_polarities(main_component)?;
let configured = Configured {
controller_id,
protocol_description,
bindings: Default::default(),
polarities,
main_component: main_component.to_vec(),
logger: "Logger created!\n".into(),
};
*self = Connector::Configured(configured);
Ok(())
}
/// Bind the (configured) connector's port corresponding to the
pub fn bind_port(
&mut self,
proto_port_index: usize,
binding: PortBinding,
) -> Result<(), PortBindErr> {
use PortBindErr::*;
match self {
Connector::Unconfigured { .. } => Err(NotConfigured),
Connector::Connected(_) => Err(AlreadyConnected),
Connector::Configured(configured) => {
if configured.polarities.len() <= proto_port_index {
return Err(IndexOutOfBounds);
}
configured.bindings.insert(proto_port_index, binding);
Ok(())
}
}
}
pub fn connect(&mut self, timeout: Duration) -> Result<(), ConnectErr> {
let deadline = Instant::now() + timeout;
use ConnectErr::*;
let configured = match self {
Connector::Unconfigured { .. } => return Err(NotConfigured),
Connector::Connected(_) => return Err(AlreadyConnected),
Connector::Configured(configured) => configured,
};
// 1. Unwrap bindings or err
let bound_proto_interface: Vec<(_, _)> = configured
.polarities
.iter()
.copied()
.enumerate()
.map(|(native_index, polarity)| {
let binding = configured
.bindings
.get(&native_index)
.copied()
.ok_or(PortNotBound { native_index })?;
Ok((binding, polarity))
})
.collect::<Result<Vec<(_, _)>, ConnectErr>>()?;
let (controller, native_interface) = Controller::connect(
configured.controller_id,
&configured.main_component,
configured.protocol_description.clone(),
&bound_proto_interface[..],
&mut configured.logger,
deadline,
)?;
*self = Connector::Connected(Connected {
native_interface,
sync_batches: vec![Default::default()],
controller,
});
Ok(())
}
pub fn get_mut_logger(&mut self) -> Option<&mut String> {
match self {
Connector::Configured(configured) => Some(&mut configured.logger),
Connector::Connected(connected) => Some(&mut connected.controller.inner.logger),
_ => None,
}
}
pub fn put(&mut self, native_port_index: usize, payload: Payload) -> Result<(), PortOpErr> {
use PortOpErr::*;
let connected = match self {
Connector::Connected(connected) => connected,
_ => return Err(NotConnected),
};
let (port, native_polarity) =
*connected.native_interface.get(native_port_index).ok_or(IndexOutOfBounds)?;
if native_polarity != Putter {
return Err(WrongPolarity);
}
let sync_batch = connected.sync_batches.iter_mut().last().expect("no sync batch!");
if sync_batch.puts.contains_key(&port) {
return Err(DuplicateOperation);
}
sync_batch.puts.insert(port, payload);
Ok(())
}
pub fn get(&mut self, native_port_index: usize) -> Result<(), PortOpErr> {
use PortOpErr::*;
let connected = match self {
Connector::Connected(connected) => connected,
_ => return Err(NotConnected),
};
let (port, native_polarity) =
*connected.native_interface.get(native_port_index).ok_or(IndexOutOfBounds)?;
if native_polarity != Getter {
return Err(WrongPolarity);
}
let sync_batch = connected.sync_batches.iter_mut().last().expect("no sync batch!");
if sync_batch.gets.contains(&port) {
return Err(DuplicateOperation);
}
sync_batch.gets.insert(port);
Ok(())
}
pub fn next_batch(&mut self) -> Result<usize, ()> {
let connected = match self {
Connector::Connected(connected) => connected,
_ => return Err(()),
};
connected.sync_batches.push(SyncBatch::default());
Ok(connected.sync_batches.len() - 2)
}
pub fn sync(&mut self, timeout: Duration) -> Result<usize, SyncErr> {
let deadline = Instant::now() + timeout;
use SyncErr::*;
let connected = match self {
Connector::Connected(connected) => connected,
_ => return Err(NotConnected),
};
// do the synchronous round!
let res =
connected.controller.sync_round(Some(deadline), Some(connected.sync_batches.drain(..)));
connected.sync_batches.push(SyncBatch::default());
res?;
Ok(connected.controller.inner.mono_n.result.as_mut().expect("qqqs").0)
}
pub fn read_gotten(&self, native_port_index: usize) -> Result<&[u8], ReadGottenErr> {
use ReadGottenErr::*;
let connected = match self {
Connector::Connected(connected) => connected,
_ => return Err(NotConnected),
};
let &(key, polarity) =
connected.native_interface.get(native_port_index).ok_or(IndexOutOfBounds)?;
if polarity != Getter {
return Err(WrongPolarity);
}
let result = connected.controller.inner.mono_n.result.as_ref().ok_or(NoPreviousRound)?;
let payload = result.1.get(&key).ok_or(DidNotGet)?;
Ok(payload.as_slice())
}
}
|