refine flush_if_sec behavior

The new behavior eliminates a couple unpleasant edge cases in which it
would never flush:

* if all recording stops, whatever was unflushed would stay that way
* if every recording attempt produces a 0-duration recording (such as if the
  camera sends only one frame and thus no PTS delta can be calculated),
  the list of recordings to flush would continue to grow
This commit is contained in:
Scott Lamb
2018-03-23 15:16:43 -07:00
parent addeb9d2f6
commit 91636d3193
7 changed files with 124 additions and 60 deletions

View File

@@ -34,8 +34,9 @@ use failure::Error;
use libc;
use parking_lot::Mutex;
use std::mem;
use std::sync::Arc;
use std::sync::{Arc, mpsc};
use std::thread;
use std::time::Duration as StdDuration;
use time::{Duration, Timespec};
/// Abstract interface to the system clocks. This is for testability.
@@ -48,9 +49,14 @@ pub trait Clocks : Send + Sync + 'static {
/// Causes the current thread to sleep for the specified time.
fn sleep(&self, how_long: Duration);
/// Calls `rcv.recv_timeout` or substitutes a test implementation.
fn recv_timeout<T>(&self, rcv: &mpsc::Receiver<T>,
timeout: StdDuration) -> Result<T, mpsc::RecvTimeoutError>;
}
pub fn retry_forever<T, E: Into<Error>>(clocks: &Clocks, f: &mut FnMut() -> Result<T, E>) -> T {
pub fn retry_forever<C, T, E>(clocks: &C, f: &mut FnMut() -> Result<T, E>) -> T
where C: Clocks, E: Into<Error> {
loop {
let e = match f() {
Ok(t) => return t,
@@ -85,6 +91,11 @@ impl Clocks for RealClocks {
Err(e) => warn!("Invalid duration {:?}: {}", how_long, e),
};
}
fn recv_timeout<T>(&self, rcv: &mpsc::Receiver<T>,
timeout: StdDuration) -> Result<T, mpsc::RecvTimeoutError> {
rcv.recv_timeout(timeout)
}
}
/// Logs a warning if the TimerGuard lives "too long", using the label created by a supplied
@@ -143,4 +154,14 @@ impl Clocks for SimulatedClocks {
let mut l = self.0.uptime.lock();
*l = *l + how_long;
}
/// Advances the clock by the specified amount if data is not immediately available.
fn recv_timeout<T>(&self, rcv: &mpsc::Receiver<T>,
timeout: StdDuration) -> Result<T, mpsc::RecvTimeoutError> {
let r = rcv.recv_timeout(StdDuration::new(0, 0));
if let Err(_) = r {
self.sleep(Duration::from_std(timeout).unwrap());
}
r
}
}