|
1527 | 1527 | })
|
1528 | 1528 | }
|
1529 | 1529 |
|
1530 |
| - <span class="doccomment">/// Print the read/write statistics.</span> |
1531 |
| - <span class="kw">fn</span> <span class="ident">print_stats</span><span class="op"><</span><span class="ident">R</span>: <span class="ident">Read</span><span class="op">></span>(<span class="kw-2">&</span><span class="self">self</span>, <span class="ident">i</span>: <span class="kw-2">&</span><span class="ident">Input</span><span class="op"><</span><span class="ident">R</span><span class="op">></span>, <span class="ident">prog_update</span>: <span class="kw-2">&</span><span class="ident">ProgUpdate</span>) { |
1532 |
| - <span class="kw">match</span> <span class="ident">i</span>.<span class="ident">print_level</span> { |
1533 |
| - <span class="prelude-val">Some</span>(<span class="ident">StatusLevel::None</span>) => {} |
1534 |
| - <span class="prelude-val">Some</span>(<span class="ident">StatusLevel::Noxfer</span>) => <span class="ident">prog_update</span>.<span class="ident">print_io_lines</span>(), |
1535 |
| - <span class="prelude-val">Some</span>(<span class="ident">StatusLevel::Progress</span>) <span class="op">|</span> <span class="prelude-val">None</span> => <span class="ident">prog_update</span>.<span class="ident">print_transfer_stats</span>(), |
1536 |
| - } |
1537 |
| - } |
1538 |
| - |
1539 | 1530 | <span class="doccomment">/// Flush the output to disk, if configured to do so.</span>
|
1540 | 1531 | <span class="kw">fn</span> <span class="ident">sync</span>(<span class="kw-2">&mut</span> <span class="self">self</span>) -> <span class="ident">std::io::Result</span><span class="op"><</span>()<span class="op">></span> {
|
1541 | 1532 | <span class="kw">if</span> <span class="self">self</span>.<span class="ident">cflags</span>.<span class="ident">fsync</span> {
|
|
1585 | 1576 |
|
1586 | 1577 | <span class="comment">// Start a thread that reports transfer progress.</span>
|
1587 | 1578 | <span class="comment">//</span>
|
1588 |
| - <span class="comment">// When `status=progress` is given on the command-line, the</span> |
1589 |
| - <span class="comment">// `dd` program reports its progress every second or so. We</span> |
| 1579 | + <span class="comment">// The `dd` program reports its progress after every block is written,</span> |
| 1580 | + <span class="comment">// at most every 1 second, and only if `status=progress` is given on</span> |
| 1581 | + <span class="comment">// the command-line or a SIGUSR1 signal is received. We</span> |
1590 | 1582 | <span class="comment">// perform this reporting in a new thread so as not to take</span>
|
1591 | 1583 | <span class="comment">// any CPU time away from the actual reading and writing of</span>
|
1592 | 1584 | <span class="comment">// data. We send a `ProgUpdate` from the transmitter `prog_tx`</span>
|
1593 | 1585 | <span class="comment">// to the receives `rx`, and the receiver prints the transfer</span>
|
1594 | 1586 | <span class="comment">// information.</span>
|
1595 | 1587 | <span class="kw">let</span> (<span class="ident">prog_tx</span>, <span class="ident">rx</span>) <span class="op">=</span> <span class="ident">mpsc::channel</span>();
|
1596 |
| - <span class="ident">thread::spawn</span>(<span class="ident">gen_prog_updater</span>(<span class="ident">rx</span>, <span class="ident">i</span>.<span class="ident">print_level</span>)); |
| 1588 | + <span class="kw">let</span> <span class="ident">output_thread</span> <span class="op">=</span> <span class="ident">thread::spawn</span>(<span class="ident">gen_prog_updater</span>(<span class="ident">rx</span>, <span class="ident">i</span>.<span class="ident">print_level</span>)); |
| 1589 | + <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">progress_as_secs</span> <span class="op">=</span> <span class="number">0</span>; |
1597 | 1590 |
|
1598 | 1591 | <span class="comment">// Create a common buffer with a capacity of the block size.</span>
|
1599 | 1592 | <span class="comment">// This is the max size needed.</span>
|
|
1618 | 1611 | }
|
1619 | 1612 | <span class="kw">let</span> <span class="ident">wstat_update</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">write_blocks</span>(<span class="kw-2">&</span><span class="ident">buf</span>)<span class="question-mark">?</span>;
|
1620 | 1613 |
|
1621 |
| - <span class="comment">// Update the read/write stats and inform the progress thread.</span> |
| 1614 | + <span class="comment">// Update the read/write stats and inform the progress thread once per second.</span> |
1622 | 1615 | <span class="comment">//</span>
|
1623 | 1616 | <span class="comment">// If the receiver is disconnected, `send()` returns an</span>
|
1624 | 1617 | <span class="comment">// error. Since it is just reporting progress and is not</span>
|
1625 | 1618 | <span class="comment">// crucial to the operation of `dd`, let's just ignore the</span>
|
1626 | 1619 | <span class="comment">// error.</span>
|
1627 | 1620 | <span class="ident">rstat</span> <span class="op">+</span><span class="op">=</span> <span class="ident">rstat_update</span>;
|
1628 | 1621 | <span class="ident">wstat</span> <span class="op">+</span><span class="op">=</span> <span class="ident">wstat_update</span>;
|
1629 |
| - <span class="kw">let</span> <span class="ident">prog_update</span> <span class="op">=</span> <span class="ident">ProgUpdate::new</span>(<span class="ident">rstat</span>, <span class="ident">wstat</span>, <span class="ident">start</span>.<span class="ident">elapsed</span>()); |
1630 |
| - <span class="ident">prog_tx</span>.<span class="ident">send</span>(<span class="ident">prog_update</span>).<span class="ident">unwrap_or</span>(()); |
| 1622 | + <span class="kw">let</span> <span class="ident">prog_update</span> <span class="op">=</span> <span class="ident">ProgUpdate::new</span>(<span class="ident">rstat</span>, <span class="ident">wstat</span>, <span class="ident">start</span>.<span class="ident">elapsed</span>(), <span class="bool-val">false</span>); |
| 1623 | + <span class="kw">if</span> <span class="ident">prog_update</span>.<span class="ident">duration</span>.<span class="ident">as_secs</span>() <span class="op">></span><span class="op">=</span> <span class="ident">progress_as_secs</span> { |
| 1624 | + <span class="ident">progress_as_secs</span> <span class="op">=</span> <span class="ident">prog_update</span>.<span class="ident">duration</span>.<span class="ident">as_secs</span>() <span class="op">+</span> <span class="number">1</span>; |
| 1625 | + <span class="ident">prog_tx</span>.<span class="ident">send</span>(<span class="ident">prog_update</span>).<span class="ident">unwrap_or</span>(()); |
| 1626 | + } |
1631 | 1627 | }
|
1632 | 1628 |
|
1633 | 1629 | <span class="comment">// Flush the output, if configured to do so.</span>
|
1634 | 1630 | <span class="self">self</span>.<span class="ident">sync</span>()<span class="question-mark">?</span>;
|
1635 | 1631 |
|
1636 | 1632 | <span class="comment">// Print the final read/write statistics.</span>
|
1637 |
| - <span class="kw">let</span> <span class="ident">prog_update</span> <span class="op">=</span> <span class="ident">ProgUpdate::new</span>(<span class="ident">rstat</span>, <span class="ident">wstat</span>, <span class="ident">start</span>.<span class="ident">elapsed</span>()); |
1638 |
| - <span class="self">self</span>.<span class="ident">print_stats</span>(<span class="kw-2">&</span><span class="ident">i</span>, <span class="kw-2">&</span><span class="ident">prog_update</span>); |
| 1633 | + <span class="kw">let</span> <span class="ident">prog_update</span> <span class="op">=</span> <span class="ident">ProgUpdate::new</span>(<span class="ident">rstat</span>, <span class="ident">wstat</span>, <span class="ident">start</span>.<span class="ident">elapsed</span>(), <span class="bool-val">true</span>); |
| 1634 | + <span class="ident">prog_tx</span>.<span class="ident">send</span>(<span class="ident">prog_update</span>).<span class="ident">unwrap_or</span>(()); |
| 1635 | + <span class="comment">// Wait for the output thread to finish</span> |
| 1636 | + <span class="ident">output_thread</span> |
| 1637 | + .<span class="ident">join</span>() |
| 1638 | + .<span class="ident">expect</span>(<span class="string">"Failed to join with the output thread."</span>); |
1639 | 1639 | <span class="prelude-val">Ok</span>(())
|
1640 | 1640 | }
|
1641 | 1641 | }
|
|
0 commit comments