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]
delegate = "0.8"
paste = "1.0"
dyn-clone = "1.0"
embed-doc-image = "0.1"
[dependencies.dyn-clone]
version = "1.0"
optional = true
[dependencies.hashbrown]
version = "0.13"
optional = true
@ -58,7 +61,7 @@ version = "1.0"
[features]
default = ["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"]
crossbeam = ["crossbeam-channel"]
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::tm::PusTm;
use spacepackets::tm::PusTmSecondaryHeader;
use spacepackets::{SpHeader, MAX_APID};
use crate::pus::EcssTmSender;
#[cfg(feature = "alloc")]
pub use allocvec::EventReporter;

View File

@ -4,6 +4,7 @@
//!
//! 1. PUS Verification Service 1 module inside [verification]. Requires [alloc] support.
use downcast_rs::{impl_downcast, Downcast};
#[cfg(feature = "alloc")]
use dyn_clone::DynClone;
use spacepackets::ecss::PusError;
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
/// is implemented to allow passing the sender as a boxed trait object and still retrieve the
/// concrete type at a later point.
pub trait EcssTmSender: Downcast + Send + DynClone {
pub trait EcssTmSender: Downcast + Send {
type Error;
fn send_tm(&mut self, tm: PusTm) -> Result<(), EcssTmError<Self::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>> {
if len > cap {

View File

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

View File

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