I'm trying to share an Arc<Mutex<T>>
with a closure. I get the error that closure is
FnOncebecause it moves the variable
shared_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.