How to copy and write to device with progress

I have a source file called input.iso and I want to write its content to /dev/sdx in a separate thread. I also have a written: Arc<RefCell<usize>> keep track of of the copy progress. I have to_write: Arc<usize> too. I also need to be able to know if the writer thread finished successfully.

I need to be able to display progress of this progress. I have a timer function running in the UI thread that periodically is going to read the progress. How can I achieve this?

I'm stuck because

  1. I don't know how to determine if a thread finished. thread::spawn returns a join handle.

  2. the write method returns how many bytes that have been written. How can I start from that amount of byte in input.iso next time I call write?

Here's a rough sketch of what I want to achieve:

fn set_start() {
  let written = Arc::<usize>::new(0);
  let to_write = get_size();

  let (input, output) = get_io();
  let task =   thread::spawn(move ||{
    // written +=  write;
  });

  let progress_bar = make_pb();
  let pb_timeout = gtk::timeout_add(
    20 /*interval*/, 
    |_| {
        // check written
      // do something with written
     return task.finished;
    }
  )
}

You can't ask the JoinHandle directly, but what about adding a callback that gets triggered when your closure finishes? Or if it's possible that the code may panic/return early, you could use a "guard" type which invokes the callback on Drop.

Copying from a std::io::Reader to a std::io::Writer is usually done by reading to some intermediate buffer then immediately writing it out again, the std::io::copy() function is a helper for doing exactly this.

What I'd do is look at the source code for std::io::copy() and adapt it to call a callback after every write that updates your shared counter.

You'll need to adapt it to suit Gtk, but this example should point you in the right direction.

I'm also using an Arc<AtomicUsize> instead of an Arc<RefCell<usize>> because RefCell can't be sent across threads. You also don't need to put to_write behind an Arc. If it's never going to change, just copy it.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.