title: Future created by async block is not `Send` because of *mut u8
body: <p>I was able to proceed forward to implement my asynchronous udp server. However I have this error showing up twice because my variable <strong>data has type <code>*mut u8</code> which is not <code>Send</code></strong>:</p>
  <pre class="lang-none prettyprint-override"><code>error: future cannot be sent between threads safely
   help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `*mut u8`
  note: captured value is not `Send`
  </code></pre>
  <p>And the code (MRE):</p>
  <pre class="lang-rs prettyprint-override"><code>use std::error::Error;
  use std::time::Duration;
  use std::env;
  use tokio::net::UdpSocket;
  use tokio::{sync::mpsc, task, time}; // 1.4.0
  use std::alloc::{alloc, Layout};
  use std::mem;
  use std::mem::MaybeUninit;
  use std::net::SocketAddr;
  
  const UDP_HEADER: usize = 8;
  const IP_HEADER: usize = 20;
  const AG_HEADER: usize = 4;
  const MAX_DATA_LENGTH: usize = (64 * 1024 - 1) - UDP_HEADER - IP_HEADER;
  const MAX_CHUNK_SIZE: usize = MAX_DATA_LENGTH - AG_HEADER;
  const MAX_DATAGRAM_SIZE: usize = 0x10000;
  
  /// A wrapper for [ptr::copy_nonoverlapping] with different argument order (same as original memcpy)
  unsafe fn memcpy(dst_ptr: *mut u8, src_ptr: *const u8, len: usize) {
      std::ptr::copy_nonoverlapping(src_ptr, dst_ptr, len);
  }
  
  // Different from https://doc.rust-lang.org/std/primitive.u32.html#method.next_power_of_two
  // Returns the [exponent] from the smallest power of two greater than or equal to n.
  const fn next_power_of_two_exponent(n: u32) -&gt; u32 {
      return 32 - (n - 1).leading_zeros();
  }
  
  async fn run_server(socket: UdpSocket) {
      let mut missing_indexes: Vec&lt;u16&gt; = Vec::new();
      let mut peer_addr = MaybeUninit::&lt;SocketAddr&gt;::uninit();
      let mut data = std::ptr::null_mut(); // ptr for the file bytes
      let mut len: usize = 0; // total len of bytes that will be written
      let mut layout = MaybeUninit::&lt;Layout&gt;::uninit();
      let mut buf = [0u8; MAX_DATA_LENGTH];
      let mut start = false;
      let (debounce_tx, mut debounce_rx) = mpsc::channel::&lt;(usize, SocketAddr)&gt;(3300);
      let (network_tx, mut network_rx) = mpsc::channel::&lt;(usize, SocketAddr)&gt;(3300);
  
      loop {
          // Listen for events
          let debouncer = task::spawn(async move {
              let duration = Duration::from_millis(3300);
  
              loop {
                  match time::timeout(duration, debounce_rx.recv()).await {
                      Ok(Some((size, peer))) =&gt; {
                          eprintln!(&quot;Network activity&quot;);
                      }
                      Ok(None) =&gt; {
                          if start == true {
                              eprintln!(&quot;Debounce finished&quot;);
                              break;
                          }
                      }
                      Err(_) =&gt; {
                          eprintln!(&quot;{:?} since network activity&quot;, duration);
                      }
                  }
              }
          });
          // Listen for network activity
          let server = task::spawn({
              // async{
              let debounce_tx = debounce_tx.clone();
              async move {
                  while let Some((size, peer)) = network_rx.recv().await {
                      // Received a new packet
                      debounce_tx.send((size, peer)).await.expect(&quot;Unable to talk to debounce&quot;);
                      eprintln!(&quot;Received a packet {} from: {}&quot;, size, peer);
  
                      let packet_index: u16 = (buf[0] as u16) &lt;&lt; 8 | buf[1] as u16;
  
                      if start == false { // first bytes of a new file: initialization // TODO: ADD A MUTEX to prevent many initializations
                          start = true;
                          let chunks_cnt: u32 = (buf[2] as u32) &lt;&lt; 8 | buf[3] as u32;
                          let n: usize = MAX_DATAGRAM_SIZE &lt;&lt; next_power_of_two_exponent(chunks_cnt);
                          unsafe {
                              layout.as_mut_ptr().write(Layout::from_size_align_unchecked(n, mem::align_of::&lt;u8&gt;()));
                              
                              
                              // /!\  data has type `*mut u8` which is not `Send`
                              data = alloc(layout.assume_init());
                              
                              peer_addr.as_mut_ptr().write(peer);
                          }
                          let a: Vec&lt;u16&gt; = vec![0; chunks_cnt as usize]; //(0..chunks_cnt).map(|x| x as u16).collect(); // create a sorted vector with all the required indexes
                          missing_indexes = a;
                      }
                      missing_indexes[packet_index as usize] = 1;
                      unsafe {
                          let dst_ptr = data.offset((packet_index as usize * MAX_CHUNK_SIZE) as isize);
                          memcpy(dst_ptr, &amp;buf[AG_HEADER], size - AG_HEADER);
                      };
                      println!(&quot;receiving packet {} from: {}&quot;, packet_index, peer);
                  }
              }
          });
  
          // Prevent deadlocks
          drop(debounce_tx);
  
          match socket.recv_from(&amp;mut buf).await {
              Ok((size, src)) =&gt; {
                  network_tx.send((size, src)).await.expect(&quot;Unable to talk to network&quot;);
              }
              Err(e) =&gt; {
                  eprintln!(&quot;couldn't recieve a datagram: {}&quot;, e);
              }
          }
      }
  }
  
  #[tokio::main]
  async fn main() -&gt; Result&lt;(), Box&lt;dyn Error&gt;&gt; {
      let addr = env::args().nth(1).unwrap_or_else(|| &quot;127.0.0.1:8080&quot;.to_string());
      let socket = UdpSocket::bind(&amp;addr).await?;
      println!(&quot;Listening on: {}&quot;, socket.local_addr()?);
      run_server(socket);
      Ok(())
  }
  </code></pre>
  <p>Since I was converting from synchronous to asynchronous code I know that, potentially, multiple thread would be writing to data, and that is probably why I encounter such error. But I don't know which syntax I could use to &quot;clone&quot; the mut ptr and make it unique for each thread (and same for the buffer).</p>
  <p>As suggested by user4815162342 I think the best would be</p>
  <blockquote>
  <p>to make pointer Send by wrapping it in a struct and declaring unsafe impl Send for NewStruct {}.</p>
  </blockquote>
  <p>Any help strongly appreciated!</p>
  <p><em>PS: Full code can be found on my <a href="https://github.com/agavrel/tokio_udp_peers" rel="nofollow noreferrer">github repository</a></em></p>