dyn-clone also requires alloc..

This commit is contained in:
Robin Müller 2023-01-03 01:00:51 +01:00
parent 1fcc8d3f57
commit f8cd28c4f5
No known key found for this signature in database
GPG Key ID: 71B58F8A3CDFA9AC
5 changed files with 66 additions and 23 deletions

View File

@ -8,9 +8,12 @@ edition = "2021"
[dependencies] [dependencies]
delegate = "0.8" delegate = "0.8"
paste = "1.0" paste = "1.0"
dyn-clone = "1.0"
embed-doc-image = "0.1" embed-doc-image = "0.1"
[dependencies.dyn-clone]
version = "1.0"
optional = true
[dependencies.hashbrown] [dependencies.hashbrown]
version = "0.13" version = "0.13"
optional = true optional = true
@ -58,7 +61,7 @@ version = "1.0"
[features] [features]
default = ["std"] default = ["std"]
std = ["downcast-rs/std", "alloc", "bus", "postcard/use-std", "crossbeam-channel/std", "serde/std", "spacepackets/std"] std = ["downcast-rs/std", "alloc", "bus", "postcard/use-std", "crossbeam-channel/std", "serde/std", "spacepackets/std"]
alloc = ["serde/alloc", "spacepackets/alloc", "hashbrown"] alloc = ["serde/alloc", "spacepackets/alloc", "hashbrown", "dyn-clone"]
serde = ["dep:serde", "spacepackets/serde"] serde = ["dep:serde", "spacepackets/serde"]
crossbeam = ["crossbeam-channel"] crossbeam = ["crossbeam-channel"]
heapless = ["dep:heapless"] heapless = ["dep:heapless"]

View File

@ -1,9 +1,10 @@
use crate::pus::{source_buffer_large_enough, EcssTmError, EcssTmSender}; use crate::pus::{source_buffer_large_enough, EcssTmError};
use spacepackets::ecss::EcssEnumeration; use spacepackets::ecss::EcssEnumeration;
use spacepackets::tm::PusTm; use spacepackets::tm::PusTm;
use spacepackets::tm::PusTmSecondaryHeader; use spacepackets::tm::PusTmSecondaryHeader;
use spacepackets::{SpHeader, MAX_APID}; use spacepackets::{SpHeader, MAX_APID};
use crate::pus::EcssTmSender;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub use allocvec::EventReporter; pub use allocvec::EventReporter;

View File

@ -4,6 +4,7 @@
//! //!
//! 1. PUS Verification Service 1 module inside [verification]. Requires [alloc] support. //! 1. PUS Verification Service 1 module inside [verification]. Requires [alloc] support.
use downcast_rs::{impl_downcast, Downcast}; use downcast_rs::{impl_downcast, Downcast};
#[cfg(feature = "alloc")]
use dyn_clone::DynClone; use dyn_clone::DynClone;
use spacepackets::ecss::PusError; use spacepackets::ecss::PusError;
use spacepackets::time::TimestampError; use spacepackets::time::TimestampError;
@ -45,14 +46,22 @@ impl<E> From<ByteConversionError> for EcssTmError<E> {
/// This sender object is responsible for sending telemetry to a TM sink. The [Downcast] trait /// This sender object is responsible for sending telemetry to a TM sink. The [Downcast] trait
/// is implemented to allow passing the sender as a boxed trait object and still retrieve the /// is implemented to allow passing the sender as a boxed trait object and still retrieve the
/// concrete type at a later point. /// concrete type at a later point.
pub trait EcssTmSender: Downcast + Send + DynClone { pub trait EcssTmSender: Downcast + Send {
type Error; type Error;
fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<Self::Error>>; fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<Self::Error>>;
} }
impl_downcast!(EcssTmSender assoc Error); impl_downcast!(EcssTmSender assoc Error);
dyn_clone::clone_trait_object!(<T> EcssTmSender<Error=T>);
#[cfg(feature = "alloc")]
pub mod alloc_mod {
use super::*;
pub trait EcssTmSenderClonable: EcssTmSender + Downcast + DynClone {}
dyn_clone::clone_trait_object!(<T> EcssTmSenderClonable<Error=T>);
impl_downcast!(EcssTmSenderClonable assoc Error);
}
pub(crate) fn source_buffer_large_enough<E>(cap: usize, len: usize) -> Result<(), EcssTmError<E>> { pub(crate) fn source_buffer_large_enough<E>(cap: usize, len: usize) -> Result<(), EcssTmError<E>> {
if len > cap { if len > cap {

View File

@ -664,6 +664,8 @@ impl VerificationReporterBasic {
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
mod alloc_mod { mod alloc_mod {
use super::*; use super::*;
use crate::pus::alloc_mod::EcssTmSenderClonable;
use crate::seq_count::SequenceCountProviderClonable;
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::vec; use alloc::vec;
use alloc::vec::Vec; use alloc::vec::Vec;
@ -671,7 +673,7 @@ mod alloc_mod {
#[derive(Clone)] #[derive(Clone)]
pub struct VerificationReporterCfg { pub struct VerificationReporterCfg {
apid: u16, apid: u16,
seq_counter: Box<dyn SequenceCountProvider<u16> + Send>, seq_counter: Box<dyn SequenceCountProviderClonable<u16> + Send>,
pub step_field_width: usize, pub step_field_width: usize,
pub fail_code_field_width: usize, pub fail_code_field_width: usize,
pub max_fail_data_len: usize, pub max_fail_data_len: usize,
@ -680,7 +682,7 @@ mod alloc_mod {
impl VerificationReporterCfg { impl VerificationReporterCfg {
pub fn new( pub fn new(
apid: u16, apid: u16,
seq_counter: Box<dyn SequenceCountProvider<u16> + Send>, seq_counter: Box<dyn SequenceCountProviderClonable<u16> + Send>,
step_field_width: usize, step_field_width: usize,
fail_code_field_width: usize, fail_code_field_width: usize,
max_fail_data_len: usize, max_fail_data_len: usize,
@ -703,7 +705,7 @@ mod alloc_mod {
#[derive(Clone)] #[derive(Clone)]
pub struct VerificationReporterWithBuf { pub struct VerificationReporterWithBuf {
source_data_buf: Vec<u8>, source_data_buf: Vec<u8>,
seq_counter: Box<dyn SequenceCountProvider<u16> + Send + 'static>, seq_counter: Box<dyn SequenceCountProviderClonable<u16> + Send + 'static>,
pub reporter: VerificationReporterBasic, pub reporter: VerificationReporterBasic,
} }
@ -892,13 +894,13 @@ mod alloc_mod {
#[derive(Clone)] #[derive(Clone)]
pub struct VerificationReporterWithSender<E> { pub struct VerificationReporterWithSender<E> {
pub reporter: VerificationReporterWithBuf, pub reporter: VerificationReporterWithBuf,
pub sender: Box<dyn EcssTmSender<Error = E>>, pub sender: Box<dyn EcssTmSenderClonable<Error = E>>,
} }
impl<E: 'static> VerificationReporterWithSender<E> { impl<E: 'static> VerificationReporterWithSender<E> {
pub fn new( pub fn new(
cfg: &VerificationReporterCfg, cfg: &VerificationReporterCfg,
sender: Box<dyn EcssTmSender<Error = E>>, sender: Box<dyn EcssTmSenderClonable<Error = E>>,
) -> Self { ) -> Self {
let reporter = VerificationReporterWithBuf::new(cfg); let reporter = VerificationReporterWithBuf::new(cfg);
Self::new_from_reporter(reporter, sender) Self::new_from_reporter(reporter, sender)
@ -906,7 +908,7 @@ mod alloc_mod {
pub fn new_from_reporter( pub fn new_from_reporter(
reporter: VerificationReporterWithBuf, reporter: VerificationReporterWithBuf,
sender: Box<dyn EcssTmSender<Error = E>>, sender: Box<dyn EcssTmSenderClonable<Error = E>>,
) -> Self { ) -> Self {
Self { reporter, sender } Self { reporter, sender }
} }
@ -1004,6 +1006,7 @@ mod stdmod {
use super::alloc_mod::VerificationReporterWithSender; use super::alloc_mod::VerificationReporterWithSender;
use super::*; use super::*;
use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr, StoreError}; use crate::pool::{ShareablePoolProvider, SharedPool, StoreAddr, StoreError};
use crate::pus::alloc_mod::EcssTmSenderClonable;
use delegate::delegate; use delegate::delegate;
use spacepackets::tm::PusTm; use spacepackets::tm::PusTm;
use std::sync::{mpsc, Arc, Mutex, RwLockWriteGuard}; use std::sync::{mpsc, Arc, Mutex, RwLockWriteGuard};
@ -1085,8 +1088,8 @@ mod stdmod {
} }
); );
} }
unsafe impl Sync for MpscVerifSender {}
unsafe impl Send for MpscVerifSender {} impl EcssTmSenderClonable for MpscVerifSender {}
impl SendBackend for crossbeam_channel::Sender<StoreAddr> { impl SendBackend for crossbeam_channel::Sender<StoreAddr> {
fn send(&self, addr: StoreAddr) -> Result<(), StoreAddr> { fn send(&self, addr: StoreAddr) -> Result<(), StoreAddr> {
@ -1123,11 +1126,8 @@ mod stdmod {
); );
} }
// TODO: Are those really necessary? Check with test..
#[cfg(feature = "crossbeam")] #[cfg(feature = "crossbeam")]
unsafe impl Sync for CrossbeamVerifSender {} impl EcssTmSenderClonable for CrossbeamVerifSender {}
#[cfg(feature = "crossbeam")]
unsafe impl Send for CrossbeamVerifSender {}
impl<S: SendBackend + Clone + 'static> EcssTmSender for StdSenderBase<S> { impl<S: SendBackend + Clone + 'static> EcssTmSender for StdSenderBase<S> {
type Error = StdVerifSenderError; type Error = StdVerifSenderError;
@ -1157,11 +1157,13 @@ mod stdmod {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::pool::{LocalPool, PoolCfg, SharedPool};
use crate::pus::alloc_mod::EcssTmSenderClonable;
use crate::pus::tests::CommonTmInfo; use crate::pus::tests::CommonTmInfo;
use crate::pus::verification::{ use crate::pus::verification::{
EcssTmError, EcssTmSender, FailParams, FailParamsWithStep, RequestId, TcStateNone, EcssTmError, EcssTmSender, FailParams, FailParamsWithStep, MpscVerifSender, RequestId,
VerificationReporterCfg, VerificationReporterWithBuf, VerificationReporterWithSender, TcStateNone, VerificationReporterCfg, VerificationReporterWithBuf,
VerificationToken, VerificationReporterWithSender, VerificationToken,
}; };
use crate::seq_count::SimpleSeqCountProvider; use crate::seq_count::SimpleSeqCountProvider;
use alloc::boxed::Box; use alloc::boxed::Box;
@ -1171,8 +1173,14 @@ mod tests {
use spacepackets::tm::PusTm; use spacepackets::tm::PusTm;
use spacepackets::{ByteConversionError, SpHeader}; use spacepackets::{ByteConversionError, SpHeader};
use std::collections::VecDeque; use std::collections::VecDeque;
use std::sync::{mpsc, Arc, RwLock};
use std::vec;
use std::vec::Vec; use std::vec::Vec;
fn is_send<T: Send>(_: &T) {}
#[allow(dead_code)]
fn is_sync<T: Sync>(_: &T) {}
const TEST_APID: u16 = 0x02; const TEST_APID: u16 = 0x02;
const EMPTY_STAMP: [u8; 7] = [0; 7]; const EMPTY_STAMP: [u8; 7] = [0; 7];
@ -1213,6 +1221,8 @@ mod tests {
} }
} }
impl EcssTmSenderClonable for TestSender {}
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
struct DummyError {} struct DummyError {}
#[derive(Default, Clone)] #[derive(Default, Clone)]
@ -1225,6 +1235,8 @@ mod tests {
} }
} }
impl EcssTmSenderClonable for FallibleSender {}
struct TestBase<'a> { struct TestBase<'a> {
vr: VerificationReporterWithBuf, vr: VerificationReporterWithBuf,
#[allow(dead_code)] #[allow(dead_code)]
@ -1309,6 +1321,15 @@ mod tests {
assert_eq!(info, cmp_info); assert_eq!(info, cmp_info);
} }
#[test]
fn test_mpsc_verif_send_sync() {
let pool = LocalPool::new(PoolCfg::new(vec![(8, 8)]));
let shared_pool: SharedPool = Arc::new(RwLock::new(Box::new(pool)));
let (tx, _) = mpsc::channel();
let mpsc_verif_sender = MpscVerifSender::new(shared_pool, tx);
is_send(&mpsc_verif_sender);
}
#[test] #[test]
fn test_state() { fn test_state() {
let (mut b, _) = base_init(false); let (mut b, _) = base_init(false);

View File

@ -1,8 +1,9 @@
#[cfg(feature = "alloc")]
use dyn_clone::DynClone; use dyn_clone::DynClone;
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use stdmod::*; pub use stdmod::*;
pub trait SequenceCountProvider<Raw>: DynClone { pub trait SequenceCountProvider<Raw> {
fn get(&self) -> Raw; fn get(&self) -> Raw;
fn increment(&mut self); fn increment(&mut self);
fn get_and_increment(&mut self) -> Raw { fn get_and_increment(&mut self) -> Raw {
@ -12,13 +13,16 @@ pub trait SequenceCountProvider<Raw>: DynClone {
} }
} }
#[cfg(feature = "alloc")]
pub trait SequenceCountProviderClonable<Raw>: SequenceCountProvider<Raw> + DynClone {}
#[cfg(feature = "alloc")]
dyn_clone::clone_trait_object!(SequenceCountProviderClonable<u16>);
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct SimpleSeqCountProvider { pub struct SimpleSeqCountProvider {
seq_count: u16, seq_count: u16,
} }
dyn_clone::clone_trait_object!(SequenceCountProvider<u16>);
impl SequenceCountProvider<u16> for SimpleSeqCountProvider { impl SequenceCountProvider<u16> for SimpleSeqCountProvider {
fn get(&self) -> u16 { fn get(&self) -> u16 {
self.seq_count self.seq_count
@ -33,6 +37,9 @@ impl SequenceCountProvider<u16> for SimpleSeqCountProvider {
} }
} }
#[cfg(feature = "alloc")]
impl SequenceCountProviderClonable<u16> for SimpleSeqCountProvider {}
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub mod stdmod { pub mod stdmod {
use super::*; use super::*;
@ -57,4 +64,6 @@ pub mod stdmod {
self.seq_count.fetch_add(1, Ordering::SeqCst) self.seq_count.fetch_add(1, Ordering::SeqCst)
} }
} }
impl SequenceCountProviderClonable<u16> for SyncSeqCountProvider {}
} }