2021年3月6日星期六

Arc

I'm trying to share an Arc<Mutex<T>> with a closure. I get the error that closure is FnOncebecause it moves the variableshared_wake_deque_ out of its environment:

use core::task::{Context, Poll, Waker};  use hyper::client::connect::{Connection, Connected};  use std::sync::{Arc, Mutex};  use std::collections::VecDeque;    pub type OnPollRead = Arc<dyn Fn(&mut Context<'_>, &mut tokio::io::ReadBuf<'_>) -> Poll<std::io::Result<()>> + Send + Sync>;  pub type OnPollWrite = Arc<dyn Fn(&mut Context<'_>, &[u8]) -> Poll<core::result::Result<usize, std::io::Error>> + Send + Sync>;    #[derive(Clone)]  pub struct CustomTransporter {      on_poll_read: Option<OnPollRead>,      on_poll_write: Option<OnPollWrite>,  }    pub struct OVPNClient {  }    impl OVPNClient {      pub fn send(&self, buffer: &[u8]) {                }  }    unsafe impl Send for OVPNClient {}      unsafe impl Send for CustomTransporter {}    impl CustomTransporter {      pub fn new(on_poll_read: Option<OnPollRead>, on_poll_write: Option<OnPollWrite>) -> CustomTransporter {          CustomTransporter{              on_poll_read: on_poll_read,              on_poll_write: on_poll_write          }      }  }    fn main () {      let openvpn_client = Arc::new(Mutex::new(OVPNClient{}));        let shared_wake_deque = Arc::new(Mutex::new(VecDeque::<Waker>::new()));            let shared_wake_deque_ = shared_wake_deque.clone();      let on_poll_read = Arc::new(|context: &mut Context, buffer: &mut tokio::io::ReadBuf| -> Poll<std::io::Result<()>> {          let shared_wake_deque__ = shared_wake_deque_;          Poll::Ready(Ok(()))      });        let on_poll_write = Arc::new(|context: &mut Context, buffer: &[u8]| -> Poll<core::result::Result<usize, std::io::Error>>{          openvpn_client.lock().unwrap().send(buffer);          Poll::Ready(Ok(0))      });        let connector = CustomTransporter::new(Some(on_poll_read), Some(on_poll_write));  }  

Error:

error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`    --> src/main.rs:44:33     |  44 |     let on_poll_read = Arc::new(|context: &mut Context, buffer: &mut tokio::io::ReadBuf| -> Poll<std::io::Result<()>> {     |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this closure implements `FnOnce`, not `Fn`  45 |         let shared_wake_deque__ = shared_wake_deque_;     |                                   ------------------ closure is `FnOnce` because it moves the variable `shared_wake_deque_` out of its environment  ...  54 |     let connector = CustomTransporter::new(Some(on_poll_read), Some(on_poll_write));     |                                                 ------------ the requirement to implement `Fn` derives from here  

I get that moving can only occur one time. I didn't even made the closure move. As you see, I'm trying to use a clone of the Arc<Mutex<T>> so I'm not exactly moving it. You can see that I tried cloning so I move a variable that is used just on this closure and never anymore, but it didn't work.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d996163f5d2a6e9322af9a7472581ce6

https://stackoverflow.com/questions/66502376/arcmutext-inside-closure-expected-a-closure-that-implements-the-fn-trait March 06, 2021 at 12:30PM

没有评论:

发表评论