fix qemu launcher bug (#3206)
* no more shellscript * metadatas * clp * clippo * fix bug * taplo * Merge branch 'qemu_launcher_insane' of github.com:AFLplusplus/LibAFL into qemu_launcher_insane * fix wrong code
This commit is contained in:
parent
60c05396da
commit
390008e1d5
@ -2,9 +2,10 @@ use std::env;
|
||||
|
||||
use libafl::{
|
||||
corpus::{InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||
events::ClientDescription,
|
||||
events::{
|
||||
ClientDescription, EventFirer, EventReceiver, EventRestarter, ProgressReporter, SendExiting,
|
||||
},
|
||||
inputs::BytesInput,
|
||||
monitors::Monitor,
|
||||
state::StdState,
|
||||
Error,
|
||||
};
|
||||
@ -14,11 +15,7 @@ use libafl_qemu::modules::{
|
||||
utils::filters::StdAddressFilter, DrCovModule, InjectionModule,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
harness::Harness,
|
||||
instance::{ClientMgr, Instance},
|
||||
options::FuzzerOptions,
|
||||
};
|
||||
use crate::{harness::Harness, instance::Instance, options::FuzzerOptions};
|
||||
|
||||
#[expect(clippy::module_name_repetitions)]
|
||||
pub type ClientState =
|
||||
@ -51,12 +48,19 @@ impl Client<'_> {
|
||||
}
|
||||
|
||||
#[expect(clippy::too_many_lines)]
|
||||
pub fn run<M: Monitor>(
|
||||
pub fn run<EM>(
|
||||
&self,
|
||||
state: Option<ClientState>,
|
||||
mgr: ClientMgr<M>,
|
||||
mgr: EM,
|
||||
client_description: ClientDescription,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
EM: EventFirer<BytesInput, ClientState>
|
||||
+ EventRestarter<ClientState>
|
||||
+ ProgressReporter<ClientState>
|
||||
+ SendExiting
|
||||
+ EventReceiver<BytesInput, ClientState>,
|
||||
{
|
||||
let core_id = client_description.core_id();
|
||||
let mut args = self.args()?;
|
||||
Harness::edit_args(&mut args);
|
||||
|
@ -5,20 +5,16 @@ use std::{
|
||||
};
|
||||
|
||||
use clap::Parser;
|
||||
#[cfg(feature = "simplemgr")]
|
||||
use libafl::events::SimpleEventManager;
|
||||
#[cfg(not(feature = "simplemgr"))]
|
||||
use libafl::events::{EventConfig, Launcher, LlmpEventManagerBuilder, MonitorTypedEventManager};
|
||||
use libafl::events::{EventConfig, Launcher};
|
||||
use libafl::{
|
||||
events::ClientDescription,
|
||||
events::{ClientDescription, SimpleEventManager},
|
||||
monitors::{tui::TuiMonitor, Monitor, MultiMonitor},
|
||||
Error,
|
||||
};
|
||||
#[cfg(not(feature = "simplemgr"))]
|
||||
use libafl_bolts::shmem::{ShMemProvider, StdShMemProvider};
|
||||
use libafl_bolts::{core_affinity::CoreId, current_time};
|
||||
#[cfg(not(feature = "simplemgr"))]
|
||||
use libafl_bolts::{llmp::LlmpBroker, staterestore::StateRestorer, tuples::tuple_list};
|
||||
#[cfg(unix)]
|
||||
use {
|
||||
nix::unistd::dup,
|
||||
@ -84,7 +80,8 @@ impl Fuzzer {
|
||||
{
|
||||
// The shared memory allocator
|
||||
#[cfg(not(feature = "simplemgr"))]
|
||||
let mut shmem_provider = StdShMemProvider::new()?;
|
||||
let shmem_provider = StdShMemProvider::new()?;
|
||||
|
||||
/* If we are running in verbose, don't provide a replacement stdout, otherwise, use /dev/null */
|
||||
#[cfg(not(feature = "simplemgr"))]
|
||||
let stdout = if self.options.verbose {
|
||||
@ -95,45 +92,10 @@ impl Fuzzer {
|
||||
|
||||
let client = Client::new(&self.options);
|
||||
|
||||
#[cfg(not(feature = "simplemgr"))]
|
||||
if self.options.rerun_input.is_some() {
|
||||
// If we want to rerun a single input but we use a restarting mgr, we'll have to create a fake restarting mgr that doesn't actually restart.
|
||||
// It's not pretty but better than recompiling with simplemgr.
|
||||
|
||||
// Just a random number, let's hope it's free :)
|
||||
let broker_port = 13120;
|
||||
let _fake_broker = LlmpBroker::create_attach_to_tcp(
|
||||
shmem_provider.clone(),
|
||||
tuple_list!(),
|
||||
broker_port,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// To rerun an input, instead of using a launcher, we create dummy parameters and run the client directly.
|
||||
// NOTE: This is a hack for debugging that that will only work for non-crashing inputs.
|
||||
return client.run(
|
||||
None,
|
||||
MonitorTypedEventManager::<_, M>::new(
|
||||
LlmpEventManagerBuilder::builder()
|
||||
.build_on_port(
|
||||
shmem_provider.clone(),
|
||||
broker_port,
|
||||
EventConfig::AlwaysUnique,
|
||||
Some(StateRestorer::new(
|
||||
shmem_provider.new_shmem(0x1000).unwrap(),
|
||||
)),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
ClientDescription::new(0, 0, CoreId(0)),
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "simplemgr")]
|
||||
if self.options.rerun_input.is_some() {
|
||||
return client.run(
|
||||
None,
|
||||
SimpleEventManager::new(monitor),
|
||||
SimpleEventManager::new(monitor.clone()),
|
||||
ClientDescription::new(0, 0, CoreId(0)),
|
||||
);
|
||||
}
|
||||
@ -141,7 +103,7 @@ impl Fuzzer {
|
||||
#[cfg(feature = "simplemgr")]
|
||||
return client.run(
|
||||
None,
|
||||
SimpleEventManager::new(monitor),
|
||||
SimpleEventManager::new(monitor.clone()),
|
||||
ClientDescription::new(0, 0, CoreId(0)),
|
||||
);
|
||||
|
||||
@ -152,7 +114,7 @@ impl Fuzzer {
|
||||
.broker_port(self.options.port)
|
||||
.configuration(EventConfig::from_build_id())
|
||||
.monitor(monitor)
|
||||
.run_client(|s, m, c| client.run(s, MonitorTypedEventManager::<_, M>::new(m), c))
|
||||
.run_client(|s, m, c| client.run(s, m, c))
|
||||
.cores(&self.options.cores)
|
||||
.stdout_file(stdout)
|
||||
.stderr_file(stdout)
|
||||
|
@ -1,19 +1,16 @@
|
||||
use core::fmt::Debug;
|
||||
use std::{fs, marker::PhantomData, ops::Range, process};
|
||||
use std::{fs, ops::Range, process};
|
||||
|
||||
#[cfg(feature = "simplemgr")]
|
||||
use libafl::events::SimpleEventManager;
|
||||
#[cfg(not(feature = "simplemgr"))]
|
||||
use libafl::events::{LlmpRestartingEventManager, MonitorTypedEventManager};
|
||||
use libafl::{
|
||||
corpus::{Corpus, HasCurrentCorpusId, InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||
events::{ClientDescription, EventRestarter},
|
||||
events::{
|
||||
ClientDescription, EventFirer, EventReceiver, EventRestarter, ProgressReporter, SendExiting,
|
||||
},
|
||||
executors::{Executor, ExitKind, ShadowExecutor},
|
||||
feedback_and_fast, feedback_or, feedback_or_fast,
|
||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
||||
fuzzer::{Evaluator, Fuzzer, StdFuzzer},
|
||||
inputs::{BytesInput, Input},
|
||||
monitors::Monitor,
|
||||
mutators::{
|
||||
havoc_mutations, token_mutations::I2SRandReplace, tokens_mutations, HavocScheduledMutator,
|
||||
StdMOptMutator, Tokens,
|
||||
@ -31,8 +28,6 @@ use libafl::{
|
||||
state::{HasCorpus, HasExecutions, HasSolutions, StdState},
|
||||
Error, HasMetadata,
|
||||
};
|
||||
#[cfg(not(feature = "simplemgr"))]
|
||||
use libafl_bolts::shmem::{StdShMem, StdShMemProvider};
|
||||
use libafl_bolts::{
|
||||
ownedref::OwnedMutSlice,
|
||||
rands::StdRand,
|
||||
@ -57,14 +52,6 @@ use crate::{harness::Harness, options::FuzzerOptions};
|
||||
pub type ClientState =
|
||||
StdState<InMemoryOnDiskCorpus<BytesInput>, BytesInput, StdRand, OnDiskCorpus<BytesInput>>;
|
||||
|
||||
#[cfg(feature = "simplemgr")]
|
||||
pub type ClientMgr<M> = SimpleEventManager<BytesInput, M, ClientState>;
|
||||
#[cfg(not(feature = "simplemgr"))]
|
||||
pub type ClientMgr<M> = MonitorTypedEventManager<
|
||||
LlmpRestartingEventManager<(), BytesInput, ClientState, StdShMem, StdShMemProvider>,
|
||||
M,
|
||||
>;
|
||||
|
||||
/*
|
||||
* The snapshot and iterations options interact as follows:
|
||||
*
|
||||
@ -87,17 +74,22 @@ pub type ClientMgr<M> = MonitorTypedEventManager<
|
||||
*/
|
||||
|
||||
#[derive(TypedBuilder)]
|
||||
pub struct Instance<'a, M: Monitor> {
|
||||
pub struct Instance<'a, EM> {
|
||||
options: &'a FuzzerOptions,
|
||||
mgr: ClientMgr<M>,
|
||||
mgr: EM,
|
||||
client_description: ClientDescription,
|
||||
#[builder(default)]
|
||||
extra_tokens: Vec<String>,
|
||||
#[builder(default=PhantomData)]
|
||||
phantom: PhantomData<M>,
|
||||
}
|
||||
|
||||
impl<M: Monitor> Instance<'_, M> {
|
||||
impl<MTEM> Instance<'_, MTEM>
|
||||
where
|
||||
MTEM: EventFirer<BytesInput, ClientState>
|
||||
+ EventRestarter<ClientState>
|
||||
+ ProgressReporter<ClientState>
|
||||
+ SendExiting
|
||||
+ EventReceiver<BytesInput, ClientState>,
|
||||
{
|
||||
fn coverage_filter(&self, qemu: Qemu) -> Result<StdAddressFilter, Error> {
|
||||
/* Conversion is required on 32-bit targets, but not on 64-bit ones */
|
||||
if let Some(includes) = &self.options.include {
|
||||
@ -438,10 +430,10 @@ impl<M: Monitor> Instance<'_, M> {
|
||||
stages: &mut ST,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
ST: StagesTuple<E, ClientMgr<M>, ClientState, Z>,
|
||||
ST: StagesTuple<E, MTEM, ClientState, Z>,
|
||||
RSM: Fn(&mut E, Qemu),
|
||||
Z: Fuzzer<E, ClientMgr<M>, BytesInput, ClientState, ST>
|
||||
+ Evaluator<E, ClientMgr<M>, BytesInput, ClientState>,
|
||||
Z: Fuzzer<E, MTEM, BytesInput, ClientState, ST>
|
||||
+ Evaluator<E, MTEM, BytesInput, ClientState>,
|
||||
{
|
||||
if state.must_load_initial_inputs() {
|
||||
let corpus_dirs = [self.options.input_dir()];
|
||||
|
@ -1,6 +1,10 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use libafl::{
|
||||
corpus::{InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||
events::ClientDescription,
|
||||
events::{
|
||||
ClientDescription, EventFirer, EventReceiver, EventRestarter, ProgressReporter, SendExiting,
|
||||
},
|
||||
inputs::BytesInput,
|
||||
monitors::Monitor,
|
||||
state::StdState,
|
||||
@ -8,11 +12,7 @@ use libafl::{
|
||||
};
|
||||
use libafl_bolts::rands::StdRand;
|
||||
|
||||
use crate::{
|
||||
instance::{ClientMgr, Instance},
|
||||
options::FuzzerOptions,
|
||||
};
|
||||
|
||||
use crate::{instance::Instance, options::FuzzerOptions};
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
pub type ClientState =
|
||||
StdState<InMemoryOnDiskCorpus<BytesInput>, BytesInput, StdRand, OnDiskCorpus<BytesInput>>;
|
||||
@ -26,12 +26,19 @@ impl Client<'_> {
|
||||
Client { options }
|
||||
}
|
||||
|
||||
pub fn run<M: Monitor>(
|
||||
pub fn run<EM>(
|
||||
&self,
|
||||
state: Option<ClientState>,
|
||||
mgr: ClientMgr<M>,
|
||||
mgr: EM,
|
||||
client_description: ClientDescription,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
EM: EventFirer<BytesInput, ClientState>
|
||||
+ EventRestarter<ClientState>
|
||||
+ ProgressReporter<ClientState>
|
||||
+ SendExiting
|
||||
+ EventReceiver<BytesInput, ClientState>,
|
||||
{
|
||||
let instance = Instance::builder()
|
||||
.options(self.options)
|
||||
.mgr(mgr)
|
||||
|
@ -7,7 +7,7 @@ use std::{
|
||||
use clap::Parser;
|
||||
use libafl::{
|
||||
events::{
|
||||
ClientDescription, EventConfig, Launcher, LlmpEventManagerBuilder, MonitorTypedEventManager,
|
||||
ClientDescription, EventConfig, Launcher, LlmpEventManagerBuilder, SimpleEventManager,
|
||||
},
|
||||
monitors::{tui::TuiMonitor, Monitor, MultiMonitor},
|
||||
Error,
|
||||
@ -83,7 +83,7 @@ impl Fuzzer {
|
||||
M: Monitor + Clone,
|
||||
{
|
||||
// The shared memory allocator
|
||||
let mut shmem_provider = StdShMemProvider::new()?;
|
||||
let shmem_provider = StdShMemProvider::new()?;
|
||||
|
||||
/* If we are running in verbose, don't provide a replacement stdout, otherwise, use /dev/null */
|
||||
let stdout = if self.options.verbose {
|
||||
@ -95,45 +95,28 @@ impl Fuzzer {
|
||||
let client = Client::new(&self.options);
|
||||
|
||||
if self.options.rerun_input.is_some() {
|
||||
// If we want to rerun a single input but we use a restarting mgr, we'll have to create a fake restarting mgr that doesn't actually restart.
|
||||
// It's not pretty but better than recompiling with simplemgr.
|
||||
|
||||
// Just a random number, let's hope it's free :)
|
||||
let broker_port = 13120;
|
||||
let _fake_broker = LlmpBroker::create_attach_to_tcp(
|
||||
shmem_provider.clone(),
|
||||
tuple_list!(),
|
||||
broker_port,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// To rerun an input, instead of using a launcher, we create dummy parameters and run the client directly.
|
||||
return client.run(
|
||||
None,
|
||||
MonitorTypedEventManager::<_, M>::new(
|
||||
LlmpEventManagerBuilder::builder().build_on_port(
|
||||
shmem_provider.clone(),
|
||||
broker_port,
|
||||
EventConfig::AlwaysUnique,
|
||||
Some(StateRestorer::new(
|
||||
shmem_provider.new_shmem(0x1000).unwrap(),
|
||||
)),
|
||||
)?,
|
||||
),
|
||||
SimpleEventManager::new(monitor.clone()),
|
||||
ClientDescription::new(0, 0, CoreId(0)),
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "simplemgr")]
|
||||
return client.run(None, SimpleEventManager::new(monitor), CoreId(0));
|
||||
return client.run(
|
||||
None,
|
||||
SimpleEventManager::new(monitor.clone()),
|
||||
ClientDescription::new(0, 0, CoreId(0)),
|
||||
);
|
||||
|
||||
// Build and run a Launcher
|
||||
#[cfg(not(feature = "simplemgr"))]
|
||||
match Launcher::builder()
|
||||
.shmem_provider(shmem_provider)
|
||||
.broker_port(self.options.port)
|
||||
.configuration(EventConfig::from_build_id())
|
||||
.monitor(monitor)
|
||||
.run_client(|s, m, c| client.run(s, MonitorTypedEventManager::<_, M>::new(m), c))
|
||||
.run_client(|s, m, c| client.run(s, m, c))
|
||||
.cores(&self.options.cores)
|
||||
.stdout_file(stdout)
|
||||
.stderr_file(stdout)
|
||||
|
@ -3,15 +3,14 @@ use std::{marker::PhantomData, process};
|
||||
use libafl::{
|
||||
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
|
||||
events::{
|
||||
ClientDescription, EventRestarter, LlmpRestartingEventManager, MonitorTypedEventManager,
|
||||
NopEventManager,
|
||||
ClientDescription, EventFirer, EventReceiver, EventRestarter, LlmpRestartingEventManager,
|
||||
NopEventManager, ProgressReporter, SendExiting,
|
||||
},
|
||||
executors::{Executor, ShadowExecutor},
|
||||
feedback_and_fast, feedback_or, feedback_or_fast,
|
||||
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
|
||||
fuzzer::{Evaluator, Fuzzer, StdFuzzer},
|
||||
inputs::BytesInput,
|
||||
monitors::Monitor,
|
||||
mutators::{
|
||||
havoc_mutations, tokens_mutations, HavocScheduledMutator, I2SRandReplace, StdMOptMutator,
|
||||
Tokens,
|
||||
@ -43,22 +42,22 @@ use crate::options::FuzzerOptions;
|
||||
pub type ClientState =
|
||||
StdState<InMemoryOnDiskCorpus<BytesInput>, BytesInput, StdRand, OnDiskCorpus<BytesInput>>;
|
||||
|
||||
pub type ClientMgr<M> = MonitorTypedEventManager<
|
||||
LlmpRestartingEventManager<(), BytesInput, ClientState, StdShMem, StdShMemProvider>,
|
||||
M,
|
||||
>;
|
||||
|
||||
#[derive(TypedBuilder)]
|
||||
pub struct Instance<'a, M: Monitor> {
|
||||
pub struct Instance<'a, EM> {
|
||||
options: &'a FuzzerOptions,
|
||||
/// The harness. We create it before forking, then `take()` it inside the client.
|
||||
mgr: ClientMgr<M>,
|
||||
mgr: EM,
|
||||
client_description: ClientDescription,
|
||||
#[builder(default=PhantomData)]
|
||||
phantom: PhantomData<M>,
|
||||
}
|
||||
|
||||
impl<M: Monitor> Instance<'_, M> {
|
||||
impl<EM> Instance<'_, EM>
|
||||
where
|
||||
EM: EventFirer<BytesInput, ClientState>
|
||||
+ EventRestarter<ClientState>
|
||||
+ ProgressReporter<ClientState>
|
||||
+ SendExiting
|
||||
+ EventReceiver<BytesInput, ClientState>,
|
||||
{
|
||||
pub fn run(mut self, state: Option<ClientState>) -> Result<(), Error> {
|
||||
let parent_cpu_id = self
|
||||
.options
|
||||
@ -229,9 +228,8 @@ impl<M: Monitor> Instance<'_, M> {
|
||||
stages: &mut ST,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
Z: Fuzzer<E, ClientMgr<M>, BytesInput, ClientState, ST>
|
||||
+ Evaluator<E, ClientMgr<M>, BytesInput, ClientState>,
|
||||
ST: StagesTuple<E, ClientMgr<M>, ClientState, Z>,
|
||||
Z: Fuzzer<E, EM, BytesInput, ClientState, ST> + Evaluator<E, EM, BytesInput, ClientState>,
|
||||
ST: StagesTuple<E, EM, ClientState, Z>,
|
||||
{
|
||||
let corpus_dirs = [self.options.input_dir()];
|
||||
|
||||
|
@ -697,137 +697,6 @@ impl HasEventManagerId for NopEventManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// An `EventManager` type that wraps another manager, but captures a `monitor` type as well.
|
||||
/// This is useful to keep the same API between managers with and without an internal `monitor`.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct MonitorTypedEventManager<EM, M> {
|
||||
inner: EM,
|
||||
phantom: PhantomData<M>,
|
||||
}
|
||||
|
||||
impl<EM, M> MonitorTypedEventManager<EM, M> {
|
||||
/// Creates a new `EventManager` that wraps another manager, but captures a `monitor` type as well.
|
||||
#[must_use]
|
||||
pub fn new(inner: EM) -> Self {
|
||||
MonitorTypedEventManager {
|
||||
inner,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<EM, I, M, S> EventFirer<I, S> for MonitorTypedEventManager<EM, M>
|
||||
where
|
||||
EM: EventFirer<I, S>,
|
||||
{
|
||||
fn should_send(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn fire(&mut self, state: &mut S, event: EventWithStats<I>) -> Result<(), Error> {
|
||||
self.inner.fire(state, event)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn log(
|
||||
&mut self,
|
||||
state: &mut S,
|
||||
severity_level: LogSeverity,
|
||||
message: String,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
S: HasExecutions,
|
||||
{
|
||||
self.inner.log(state, severity_level, message)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn configuration(&self) -> EventConfig {
|
||||
self.inner.configuration()
|
||||
}
|
||||
}
|
||||
|
||||
impl<EM, M, S> EventRestarter<S> for MonitorTypedEventManager<EM, M>
|
||||
where
|
||||
EM: EventRestarter<S>,
|
||||
{
|
||||
#[inline]
|
||||
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
||||
self.inner.on_restart(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<EM, M> SendExiting for MonitorTypedEventManager<EM, M>
|
||||
where
|
||||
EM: SendExiting,
|
||||
{
|
||||
#[inline]
|
||||
fn send_exiting(&mut self) -> Result<(), Error> {
|
||||
self.inner.send_exiting()
|
||||
}
|
||||
|
||||
fn on_shutdown(&mut self) -> Result<(), Error> {
|
||||
self.inner.on_shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
impl<EM, M> AwaitRestartSafe for MonitorTypedEventManager<EM, M>
|
||||
where
|
||||
EM: AwaitRestartSafe,
|
||||
{
|
||||
#[inline]
|
||||
fn await_restart_safe(&mut self) {
|
||||
self.inner.await_restart_safe();
|
||||
}
|
||||
}
|
||||
|
||||
impl<EM, I, M, S> EventReceiver<I, S> for MonitorTypedEventManager<EM, M>
|
||||
where
|
||||
EM: EventReceiver<I, S>,
|
||||
{
|
||||
#[inline]
|
||||
fn try_receive(&mut self, state: &mut S) -> Result<Option<(EventWithStats<I>, bool)>, Error> {
|
||||
self.inner.try_receive(state)
|
||||
}
|
||||
fn on_interesting(
|
||||
&mut self,
|
||||
_state: &mut S,
|
||||
_event_vec: EventWithStats<I>,
|
||||
) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<EM, M, S> ProgressReporter<S> for MonitorTypedEventManager<EM, M>
|
||||
where
|
||||
EM: ProgressReporter<S>,
|
||||
{
|
||||
#[inline]
|
||||
fn maybe_report_progress(
|
||||
&mut self,
|
||||
state: &mut S,
|
||||
monitor_timeout: Duration,
|
||||
) -> Result<(), Error> {
|
||||
self.inner.maybe_report_progress(state, monitor_timeout)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn report_progress(&mut self, state: &mut S) -> Result<(), Error> {
|
||||
self.inner.report_progress(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<EM, M> HasEventManagerId for MonitorTypedEventManager<EM, M>
|
||||
where
|
||||
EM: HasEventManagerId,
|
||||
{
|
||||
#[inline]
|
||||
fn mgr_id(&self) -> EventManagerId {
|
||||
self.inner.mgr_id()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user