scrap icon indicating copy to clipboard operation
scrap copied to clipboard

Make Capturer thread safe

Open snylonue opened this issue 2 years ago • 0 comments

I'm using Capturer::frame() in a async code, which blocks other code because I had to wait until a Frame is returned. I have tried to run such code with smol::unblock()

use scrap::{Capturer as RealCapturer, Display};

pub struct Screenshot {
    pub capturer: RealCapturer,
}

impl Screenshot {
    pub fn new() -> Result<Self, std::io::Error> {
        Ok(Self { capturer: RealCapturer::new(Display::primary()?)? })
    }
    pub fn capturer_size(&self) -> (usize, usize) {
        (self.capturer.width(), self.capturer.height())
    }
    pub async fn capture(&mut self) -> Result<Vec<u8>, std::io::Error> {
        smol::unblock(|| loop {
            match self.capturer.frame() {
                Ok(frame) => break Ok(frame.to_vec()), // sometimes returns an empty frame
                Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => {},
                Err(e) => break Err(e),
            }
        }).await
    }
}

but failed as Capture doesn't implements Send

`*mut winapi::d3d11::ID3D11Device` cannot be sent between threads safely
within `Screenshot`, the trait `std::marker::Send` is not implemented for `*mut winapi::d3d11::ID3D11Device`
required because of the requirements on the impl of `std::marker::Send` for `&mut Screenshot`
1 redundant requirements hidden
required because of the requirements on the impl of `std::marker::Send` for `&mut &mut Screenshot`
required because it appears within the type `[closure@src\screenshot.rs:21:23: 27:10]`

snylonue avatar Sep 21 '21 00:09 snylonue