diff --git a/dev/implementors/core/clone/trait.Clone.js b/dev/implementors/core/clone/trait.Clone.js
index 420fd9f65..702b10a07 100644
--- a/dev/implementors/core/clone/trait.Clone.js
+++ b/dev/implementors/core/clone/trait.Clone.js
@@ -1,5 +1,6 @@
(function() {var implementors = {
"uu_cp":[["impl Clone for ClobberMode"],["impl Clone for SparseMode"],["impl Clone for ReflinkMode"],["impl Clone for OverwriteMode"]],
+"uu_dd":[["impl Clone for Alarm"]],
"uu_factor":[["impl Clone for Factors"]],
"uu_install":[["impl Clone for MainFunction"]],
"uu_kill":[["impl Clone for Mode"]],
diff --git a/dev/implementors/core/fmt/trait.Debug.js b/dev/implementors/core/fmt/trait.Debug.js
index df49d2f57..b1aeab37c 100644
--- a/dev/implementors/core/fmt/trait.Debug.js
+++ b/dev/implementors/core/fmt/trait.Debug.js
@@ -1,5 +1,6 @@
(function() {var implementors = {
"uu_cp":[["impl Debug for Preserve"],["impl Debug for Attributes"],["impl Debug for Error"]],
+"uu_dd":[["impl Debug for Alarm"]],
"uu_dircolors":[["impl Debug for OutputFmt"]],
"uu_factor":[["impl Debug for Factors"]],
"uu_ln":[["impl Debug for OverwriteMode"]],
diff --git a/dev/implementors/core/marker/trait.Freeze.js b/dev/implementors/core/marker/trait.Freeze.js
index 594eabf73..c7d7cd473 100644
--- a/dev/implementors/core/marker/trait.Freeze.js
+++ b/dev/implementors/core/marker/trait.Freeze.js
@@ -2,6 +2,7 @@
"uu_base32":[["impl Freeze for Config",1,["uu_base32::base_common::Config"]]],
"uu_cp":[["impl Freeze for Error",1,["uu_cp::Error"]],["impl Freeze for ClobberMode",1,["uu_cp::ClobberMode"]],["impl Freeze for OverwriteMode",1,["uu_cp::OverwriteMode"]],["impl Freeze for ReflinkMode",1,["uu_cp::ReflinkMode"]],["impl Freeze for SparseMode",1,["uu_cp::SparseMode"]],["impl Freeze for TargetType",1,["uu_cp::TargetType"]],["impl Freeze for CopyMode",1,["uu_cp::CopyMode"]],["impl Freeze for Attributes",1,["uu_cp::Attributes"]],["impl Freeze for Preserve",1,["uu_cp::Preserve"]],["impl Freeze for Options",1,["uu_cp::Options"]]],
"uu_csplit":[["impl Freeze for CsplitOptions",1,["uu_csplit::CsplitOptions"]]],
+"uu_dd":[["impl Freeze for Alarm",1,["uu_dd::Alarm"]]],
"uu_dircolors":[["impl Freeze for OutputFmt",1,["uu_dircolors::OutputFmt"]]],
"uu_factor":[["impl !Freeze for Factors",1,["uu_factor::factor::Factors"]]],
"uu_fmt":[["impl Freeze for FmtOptions",1,["uu_fmt::FmtOptions"]]],
diff --git a/dev/implementors/core/marker/trait.Send.js b/dev/implementors/core/marker/trait.Send.js
index dcdf6588b..50d199b5c 100644
--- a/dev/implementors/core/marker/trait.Send.js
+++ b/dev/implementors/core/marker/trait.Send.js
@@ -2,6 +2,7 @@
"uu_base32":[["impl Send for Config",1,["uu_base32::base_common::Config"]]],
"uu_cp":[["impl Send for Error",1,["uu_cp::Error"]],["impl Send for ClobberMode",1,["uu_cp::ClobberMode"]],["impl Send for OverwriteMode",1,["uu_cp::OverwriteMode"]],["impl Send for ReflinkMode",1,["uu_cp::ReflinkMode"]],["impl Send for SparseMode",1,["uu_cp::SparseMode"]],["impl Send for TargetType",1,["uu_cp::TargetType"]],["impl Send for CopyMode",1,["uu_cp::CopyMode"]],["impl Send for Attributes",1,["uu_cp::Attributes"]],["impl Send for Preserve",1,["uu_cp::Preserve"]],["impl Send for Options",1,["uu_cp::Options"]]],
"uu_csplit":[["impl !Send for CsplitOptions",1,["uu_csplit::CsplitOptions"]]],
+"uu_dd":[["impl Send for Alarm",1,["uu_dd::Alarm"]]],
"uu_dircolors":[["impl Send for OutputFmt",1,["uu_dircolors::OutputFmt"]]],
"uu_factor":[["impl Send for Factors",1,["uu_factor::factor::Factors"]]],
"uu_fmt":[["impl Send for FmtOptions",1,["uu_fmt::FmtOptions"]]],
diff --git a/dev/implementors/core/marker/trait.Sync.js b/dev/implementors/core/marker/trait.Sync.js
index 8c562c47b..7edce1402 100644
--- a/dev/implementors/core/marker/trait.Sync.js
+++ b/dev/implementors/core/marker/trait.Sync.js
@@ -2,6 +2,7 @@
"uu_base32":[["impl Sync for Config",1,["uu_base32::base_common::Config"]]],
"uu_cp":[["impl Sync for Error",1,["uu_cp::Error"]],["impl Sync for ClobberMode",1,["uu_cp::ClobberMode"]],["impl Sync for OverwriteMode",1,["uu_cp::OverwriteMode"]],["impl Sync for ReflinkMode",1,["uu_cp::ReflinkMode"]],["impl Sync for SparseMode",1,["uu_cp::SparseMode"]],["impl Sync for TargetType",1,["uu_cp::TargetType"]],["impl Sync for CopyMode",1,["uu_cp::CopyMode"]],["impl Sync for Attributes",1,["uu_cp::Attributes"]],["impl Sync for Preserve",1,["uu_cp::Preserve"]],["impl Sync for Options",1,["uu_cp::Options"]]],
"uu_csplit":[["impl !Sync for CsplitOptions",1,["uu_csplit::CsplitOptions"]]],
+"uu_dd":[["impl Sync for Alarm",1,["uu_dd::Alarm"]]],
"uu_dircolors":[["impl Sync for OutputFmt",1,["uu_dircolors::OutputFmt"]]],
"uu_factor":[["impl !Sync for Factors",1,["uu_factor::factor::Factors"]]],
"uu_fmt":[["impl Sync for FmtOptions",1,["uu_fmt::FmtOptions"]]],
diff --git a/dev/implementors/core/marker/trait.Unpin.js b/dev/implementors/core/marker/trait.Unpin.js
index e62beb07c..46389050b 100644
--- a/dev/implementors/core/marker/trait.Unpin.js
+++ b/dev/implementors/core/marker/trait.Unpin.js
@@ -2,6 +2,7 @@
"uu_base32":[["impl Unpin for Config",1,["uu_base32::base_common::Config"]]],
"uu_cp":[["impl Unpin for Error",1,["uu_cp::Error"]],["impl Unpin for ClobberMode",1,["uu_cp::ClobberMode"]],["impl Unpin for OverwriteMode",1,["uu_cp::OverwriteMode"]],["impl Unpin for ReflinkMode",1,["uu_cp::ReflinkMode"]],["impl Unpin for SparseMode",1,["uu_cp::SparseMode"]],["impl Unpin for TargetType",1,["uu_cp::TargetType"]],["impl Unpin for CopyMode",1,["uu_cp::CopyMode"]],["impl Unpin for Attributes",1,["uu_cp::Attributes"]],["impl Unpin for Preserve",1,["uu_cp::Preserve"]],["impl Unpin for Options",1,["uu_cp::Options"]]],
"uu_csplit":[["impl Unpin for CsplitOptions",1,["uu_csplit::CsplitOptions"]]],
+"uu_dd":[["impl Unpin for Alarm",1,["uu_dd::Alarm"]]],
"uu_dircolors":[["impl Unpin for OutputFmt",1,["uu_dircolors::OutputFmt"]]],
"uu_factor":[["impl Unpin for Factors",1,["uu_factor::factor::Factors"]]],
"uu_fmt":[["impl Unpin for FmtOptions",1,["uu_fmt::FmtOptions"]]],
diff --git a/dev/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js b/dev/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js
index 28d430d6f..6b92f3d8b 100644
--- a/dev/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js
+++ b/dev/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js
@@ -2,6 +2,7 @@
"uu_base32":[["impl RefUnwindSafe for Config",1,["uu_base32::base_common::Config"]]],
"uu_cp":[["impl !RefUnwindSafe for Error",1,["uu_cp::Error"]],["impl RefUnwindSafe for ClobberMode",1,["uu_cp::ClobberMode"]],["impl RefUnwindSafe for OverwriteMode",1,["uu_cp::OverwriteMode"]],["impl RefUnwindSafe for ReflinkMode",1,["uu_cp::ReflinkMode"]],["impl RefUnwindSafe for SparseMode",1,["uu_cp::SparseMode"]],["impl RefUnwindSafe for TargetType",1,["uu_cp::TargetType"]],["impl RefUnwindSafe for CopyMode",1,["uu_cp::CopyMode"]],["impl RefUnwindSafe for Attributes",1,["uu_cp::Attributes"]],["impl RefUnwindSafe for Preserve",1,["uu_cp::Preserve"]],["impl RefUnwindSafe for Options",1,["uu_cp::Options"]]],
"uu_csplit":[["impl !RefUnwindSafe for CsplitOptions",1,["uu_csplit::CsplitOptions"]]],
+"uu_dd":[["impl RefUnwindSafe for Alarm",1,["uu_dd::Alarm"]]],
"uu_dircolors":[["impl RefUnwindSafe for OutputFmt",1,["uu_dircolors::OutputFmt"]]],
"uu_factor":[["impl !RefUnwindSafe for Factors",1,["uu_factor::factor::Factors"]]],
"uu_fmt":[["impl RefUnwindSafe for FmtOptions",1,["uu_fmt::FmtOptions"]]],
diff --git a/dev/implementors/core/panic/unwind_safe/trait.UnwindSafe.js b/dev/implementors/core/panic/unwind_safe/trait.UnwindSafe.js
index a55a6e849..e600ff2d5 100644
--- a/dev/implementors/core/panic/unwind_safe/trait.UnwindSafe.js
+++ b/dev/implementors/core/panic/unwind_safe/trait.UnwindSafe.js
@@ -2,6 +2,7 @@
"uu_base32":[["impl UnwindSafe for Config",1,["uu_base32::base_common::Config"]]],
"uu_cp":[["impl !UnwindSafe for Error",1,["uu_cp::Error"]],["impl UnwindSafe for ClobberMode",1,["uu_cp::ClobberMode"]],["impl UnwindSafe for OverwriteMode",1,["uu_cp::OverwriteMode"]],["impl UnwindSafe for ReflinkMode",1,["uu_cp::ReflinkMode"]],["impl UnwindSafe for SparseMode",1,["uu_cp::SparseMode"]],["impl UnwindSafe for TargetType",1,["uu_cp::TargetType"]],["impl UnwindSafe for CopyMode",1,["uu_cp::CopyMode"]],["impl UnwindSafe for Attributes",1,["uu_cp::Attributes"]],["impl UnwindSafe for Preserve",1,["uu_cp::Preserve"]],["impl UnwindSafe for Options",1,["uu_cp::Options"]]],
"uu_csplit":[["impl !UnwindSafe for CsplitOptions",1,["uu_csplit::CsplitOptions"]]],
+"uu_dd":[["impl UnwindSafe for Alarm",1,["uu_dd::Alarm"]]],
"uu_dircolors":[["impl UnwindSafe for OutputFmt",1,["uu_dircolors::OutputFmt"]]],
"uu_factor":[["impl UnwindSafe for Factors",1,["uu_factor::factor::Factors"]]],
"uu_fmt":[["impl UnwindSafe for FmtOptions",1,["uu_fmt::FmtOptions"]]],
diff --git a/dev/search-index.js b/dev/search-index.js
index f4af9399f..2114a9efc 100644
--- a/dev/search-index.js
+++ b/dev/search-index.js
@@ -116,7 +116,7 @@ var searchIndex = JSON.parse('{\
"uu_csplit":{"doc":"","t":"DLLFLLLLLFF","n":["CsplitOptions","borrow","borrow_mut","csplit","from","into","try_from","try_into","type_id","uu_app","uumain"],"q":[[0,"uu_csplit"]],"d":["Command line options for csplit.","","","Splits a file into severals according to the command line …","Returns the argument unchanged.","Calls U::from(self).","","","","",""],"i":[0,1,1,0,1,1,1,1,1,0,0],"f":[0,[[]],[[]],[[1,[2,[0]],3],[[4,[0]]]],[[]],[[]],[[],4],[[],4],[[],5],[[],6],[7,8]],"c":[],"p":[[3,"CsplitOptions"],[3,"Vec"],[8,"BufRead"],[4,"Result"],[3,"TypeId"],[3,"Command"],[8,"Args"],[15,"i32"]]},\
"uu_cut":{"doc":"","t":"FF","n":["uu_app","uumain"],"q":[[0,"uu_cut"]],"d":["",""],"i":[0,0],"f":[[[],1],[2,3]],"c":[],"p":[[3,"Command"],[8,"Args"],[15,"i32"]]},\
"uu_date":{"doc":"","t":"FF","n":["uu_app","uumain"],"q":[[0,"uu_date"]],"d":["",""],"i":[0,0],"f":[[[],1],[2,3]],"c":[],"p":[[3,"Command"],[8,"Args"],[15,"i32"]]},\
-"uu_dd":{"doc":"","t":"FF","n":["uu_app","uumain"],"q":[[0,"uu_dd"]],"d":["",""],"i":[0,0],"f":[[[],1],[2,3]],"c":[],"p":[[3,"Command"],[8,"Args"],[15,"i32"]]},\
+"uu_dd":{"doc":"","t":"DLLLLLLLLLLLLLFFL","n":["Alarm","borrow","borrow_mut","clone","clone_into","fmt","from","get_interval","into","is_triggered","to_owned","try_from","try_into","type_id","uu_app","uumain","with_interval"],"q":[[0,"uu_dd"]],"d":["A timer which triggers on a given interval","","","","","","Returns the argument unchanged.","","Calls U::from(self).","","","","","","","",""],"i":[0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1],"f":[0,[[]],[[]],[1,1],[[]],[[1,2],3],[[]],[1,4],[[]],[1,5],[[]],[[],6],[[],6],[[],7],[[],8],[9,10],[4,1]],"c":[],"p":[[3,"Alarm"],[3,"Formatter"],[6,"Result"],[3,"Duration"],[15,"bool"],[4,"Result"],[3,"TypeId"],[3,"Command"],[8,"Args"],[15,"i32"]]},\
"uu_df":{"doc":"","t":"FF","n":["uu_app","uumain"],"q":[[0,"uu_df"]],"d":["",""],"i":[0,0],"f":[[[],1],[2,3]],"c":[],"p":[[3,"Command"],[8,"Args"],[15,"i32"]]},\
"uu_dir":{"doc":"","t":"FF","n":["uu_app","uumain"],"q":[[0,"uu_dir"]],"d":["",""],"i":[0,0],"f":[[[],1],[2,3]],"c":[],"p":[[3,"Command"],[8,"Args"],[15,"i32"]]},\
"uu_dircolors":{"doc":"","t":"NNENINLLLLKLFLKKLLLFF","n":["CShell","Display","OutputFmt","Shell","StrUtils","Unknown","borrow","borrow_mut","eq","fmt","fnmatch","from","guess_syntax","into","purify","split_two","try_from","try_into","type_id","uu_app","uumain"],"q":[[0,"uu_dircolors"]],"d":["","","","","","","","","","","","Returns the argument unchanged.","","Calls U::from(self).","Remove comments and trim whitespace","Like split_whitespace() but only produce 2 components","","","","",""],"i":[1,1,0,1,0,1,1,1,1,1,11,1,0,1,11,11,1,1,1,0,0],"f":[0,0,0,0,0,0,[[]],[[]],[[1,1],2],[[1,3],4],[5,2],[[]],[[],1],[[]],[[]],[[]],[[],6],[[],6],[[],7],[[],8],[9,10]],"c":[],"p":[[4,"OutputFmt"],[15,"bool"],[3,"Formatter"],[6,"Result"],[15,"str"],[4,"Result"],[3,"TypeId"],[3,"Command"],[8,"Args"],[15,"i32"],[8,"StrUtils"]]},\
diff --git a/dev/src/uu_dd/dd.rs.html b/dev/src/uu_dd/dd.rs.html
index 2cfc4b8e1..6c5f6e6a6 100644
--- a/dev/src/uu_dd/dd.rs.html
+++ b/dev/src/uu_dd/dd.rs.html
@@ -1227,6 +1227,52 @@
1227
1228
1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
// This file is part of the uutils coreutils package.
//
// (c) Tyler Steele <tyler.steele@protonmail.com>
@@ -1265,9 +1311,12 @@
io::{AsRawFd, FromRawFd},
};
use std::path::Path;
-use std::sync::mpsc;
+use std::sync::{
+ atomic::{AtomicBool, Ordering::Relaxed},
+ mpsc, Arc,
+};
use std::thread;
-use std::time;
+use std::time::{Duration, Instant};
use clap::{crate_version, Arg, Command};
use gcd::Gcd;
@@ -1304,6 +1353,45 @@
status: Option<StatusLevel>,
}
+/// A timer which triggers on a given interval
+///
+/// After being constructed with [`Alarm::with_interval`], [`Alarm::is_triggered`]
+/// will return true once per the given [`Duration`].
+///
+/// Can be cloned, but the trigger status is shared across all instances so only
+/// the first caller each interval will yield true.
+///
+/// When all instances are dropped the background thread will exit on the next interval.
+#[derive(Debug, Clone)]
+pub struct Alarm {
+ interval: Duration,
+ trigger: Arc<AtomicBool>,
+}
+
+impl Alarm {
+ pub fn with_interval(interval: Duration) -> Self {
+ let trigger = Arc::new(AtomicBool::default());
+
+ let weak_trigger = Arc::downgrade(&trigger);
+ thread::spawn(move || {
+ while let Some(trigger) = weak_trigger.upgrade() {
+ thread::sleep(interval);
+ trigger.store(true, Relaxed);
+ }
+ });
+
+ Self { interval, trigger }
+ }
+
+ pub fn is_triggered(&self) -> bool {
+ self.trigger.swap(false, Relaxed)
+ }
+
+ pub fn get_interval(&self) -> Duration {
+ self.interval
+ }
+}
+
/// A number in blocks or bytes
///
/// Some values (seek, skip, iseek, oseek) can have values either in blocks or in bytes.
@@ -1989,7 +2077,7 @@
// of its report includes the throughput in bytes per second,
// which requires knowing how long the process has been
// running.
- let start = time::Instant::now();
+ let start = Instant::now();
// A good buffer size for reading.
//
@@ -2009,7 +2097,6 @@
// information.
let (prog_tx, rx) = mpsc::channel();
let output_thread = thread::spawn(gen_prog_updater(rx, i.settings.status));
- let mut progress_as_secs = 0;
// Optimization: if no blocks are to be written, then don't
// bother allocating any buffers.
@@ -2042,6 +2129,12 @@
// This is the max size needed.
let mut buf = vec![BUF_INIT_BYTE; bsize];
+ // Spawn a timer thread to provide a scheduled signal indicating when we
+ // should send an update of our progress to the reporting thread.
+ //
+ // This avoids the need to query the OS monotonic clock for every block.
+ let alarm = Alarm::with_interval(Duration::from_secs(1));
+
// Index in the input file where we are reading bytes and in
// the output file where we are writing bytes.
//
@@ -2100,9 +2193,8 @@
// error.
rstat += rstat_update;
wstat += wstat_update;
- let prog_update = ProgUpdate::new(rstat, wstat, start.elapsed(), false);
- if prog_update.duration.as_secs() >= progress_as_secs {
- progress_as_secs = prog_update.duration.as_secs() + 1;
+ if alarm.is_triggered() {
+ let prog_update = ProgUpdate::new(rstat, wstat, start.elapsed(), false);
prog_tx.send(prog_update).unwrap_or(());
}
}
@@ -2114,7 +2206,7 @@
output: &mut Output,
rstat: ReadStat,
wstat: WriteStat,
- start: time::Instant,
+ start: Instant,
prog_tx: &mpsc::Sender<ProgUpdate>,
output_thread: thread::JoinHandle<T>,
) -> std::io::Result<()> {
diff --git a/dev/uu_dd/all.html b/dev/uu_dd/all.html
index 1202d9455..f6c87c8bc 100644
--- a/dev/uu_dd/all.html
+++ b/dev/uu_dd/all.html
@@ -1 +1 @@
-List of all items in this crate
\ No newline at end of file
+List of all items in this crate
\ No newline at end of file
diff --git a/dev/uu_dd/fn.uu_app.html b/dev/uu_dd/fn.uu_app.html
index fad204e6c..7da3f8b5b 100644
--- a/dev/uu_dd/fn.uu_app.html
+++ b/dev/uu_dd/fn.uu_app.html
@@ -1 +1 @@
-uu_app in uu_dd - Rust
\ No newline at end of file
+uu_app in uu_dd - Rust
\ No newline at end of file
diff --git a/dev/uu_dd/fn.uumain.html b/dev/uu_dd/fn.uumain.html
index bcd8a5367..c26a4a325 100644
--- a/dev/uu_dd/fn.uumain.html
+++ b/dev/uu_dd/fn.uumain.html
@@ -1 +1 @@
-uumain in uu_dd - Rust
\ No newline at end of file
+uumain in uu_dd - Rust
\ No newline at end of file
diff --git a/dev/uu_dd/index.html b/dev/uu_dd/index.html
index a50790e52..b3a57bb6b 100644
--- a/dev/uu_dd/index.html
+++ b/dev/uu_dd/index.html
@@ -1 +1 @@
-uu_dd - Rust
\ No newline at end of file
+uu_dd - Rust
\ No newline at end of file
diff --git a/dev/uu_dd/sidebar-items.js b/dev/uu_dd/sidebar-items.js
index b75e204de..83a987837 100644
--- a/dev/uu_dd/sidebar-items.js
+++ b/dev/uu_dd/sidebar-items.js
@@ -1 +1 @@
-window.SIDEBAR_ITEMS = {"fn":["uu_app","uumain"]};
\ No newline at end of file
+window.SIDEBAR_ITEMS = {"fn":["uu_app","uumain"],"struct":["Alarm"]};
\ No newline at end of file
diff --git a/dev/uu_dd/struct.Alarm.html b/dev/uu_dd/struct.Alarm.html
new file mode 100644
index 000000000..7005ed677
--- /dev/null
+++ b/dev/uu_dd/struct.Alarm.html
@@ -0,0 +1,18 @@
+Alarm in uu_dd - Rust pub struct Alarm { /* private fields */ }
Expand description
A timer which triggers on a given interval
+After being constructed with Alarm::with_interval, Alarm::is_triggered
+will return true once per the given Duration.
+Can be cloned, but the trigger status is shared across all instances so only
+the first caller each interval will yield true.
+When all instances are dropped the background thread will exit on the next interval.
+Implementations§
source§impl Alarm
sourcepub fn with_interval(interval: Duration) -> Self
sourcepub fn is_triggered(&self) -> bool
sourcepub fn get_interval(&self) -> Duration
Trait Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for Alarm
§impl Send for Alarm
§impl Sync for Alarm
§impl Unpin for Alarm
§impl UnwindSafe for Alarm
Blanket Implementations§
\ No newline at end of file