examples/std: update to new embassy-net trait.
This commit is contained in:
		
							parent
							
								
									5eae295c8a
								
							
						
					
					
						commit
						790e4e1594
					
				@ -1,8 +1,10 @@
 | 
				
			|||||||
use std::io;
 | 
					use std::io;
 | 
				
			||||||
use std::io::{Read, Write};
 | 
					use std::io::{Read, Write};
 | 
				
			||||||
use std::os::unix::io::{AsRawFd, RawFd};
 | 
					use std::os::unix::io::{AsRawFd, RawFd};
 | 
				
			||||||
 | 
					use std::task::Context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use async_io::Async;
 | 
					use async_io::Async;
 | 
				
			||||||
 | 
					use embassy_net::device::{self, Device, DeviceCapabilities, LinkState};
 | 
				
			||||||
use log::*;
 | 
					use log::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub const SIOCGIFMTU: libc::c_ulong = 0x8921;
 | 
					pub const SIOCGIFMTU: libc::c_ulong = 0x8921;
 | 
				
			||||||
@ -125,54 +127,35 @@ impl io::Write for TunTap {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub struct TunTapDevice {
 | 
					pub struct TunTapDevice {
 | 
				
			||||||
    device: Async<TunTap>,
 | 
					    device: Async<TunTap>,
 | 
				
			||||||
    waker: Option<Waker>,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl TunTapDevice {
 | 
					impl TunTapDevice {
 | 
				
			||||||
    pub fn new(name: &str) -> io::Result<TunTapDevice> {
 | 
					    pub fn new(name: &str) -> io::Result<TunTapDevice> {
 | 
				
			||||||
        Ok(Self {
 | 
					        Ok(Self {
 | 
				
			||||||
            device: Async::new(TunTap::new(name)?)?,
 | 
					            device: Async::new(TunTap::new(name)?)?,
 | 
				
			||||||
            waker: None,
 | 
					 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use core::task::Waker;
 | 
					 | 
				
			||||||
use std::task::Context;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use embassy_net::{Device, DeviceCapabilities, LinkState, Packet, PacketBox, PacketBoxExt, PacketBuf};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Device for TunTapDevice {
 | 
					impl Device for TunTapDevice {
 | 
				
			||||||
    fn is_transmit_ready(&mut self) -> bool {
 | 
					    type RxToken<'a> = RxToken where Self: 'a;
 | 
				
			||||||
        true
 | 
					    type TxToken<'a> = TxToken<'a> where Self: 'a;
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn transmit(&mut self, pkt: PacketBuf) {
 | 
					    fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
 | 
				
			||||||
        // todo handle WouldBlock
 | 
					        let mut buf = vec![0; self.device.get_ref().mtu];
 | 
				
			||||||
        match self.device.get_mut().write(&pkt) {
 | 
					 | 
				
			||||||
            Ok(_) => {}
 | 
					 | 
				
			||||||
            Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
 | 
					 | 
				
			||||||
                info!("transmit WouldBlock");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Err(e) => panic!("transmit error: {:?}", e),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn receive(&mut self) -> Option<PacketBuf> {
 | 
					 | 
				
			||||||
        let mut pkt = PacketBox::new(Packet::new()).unwrap();
 | 
					 | 
				
			||||||
        loop {
 | 
					        loop {
 | 
				
			||||||
            match self.device.get_mut().read(&mut pkt[..]) {
 | 
					            match self.device.get_mut().read(&mut buf) {
 | 
				
			||||||
                Ok(n) => {
 | 
					                Ok(n) => {
 | 
				
			||||||
                    return Some(pkt.slice(0..n));
 | 
					                    buf.truncate(n);
 | 
				
			||||||
 | 
					                    return Some((
 | 
				
			||||||
 | 
					                        RxToken { buffer: buf },
 | 
				
			||||||
 | 
					                        TxToken {
 | 
				
			||||||
 | 
					                            device: &mut self.device,
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                    ));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
 | 
					                Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
 | 
				
			||||||
                    let ready = if let Some(w) = self.waker.as_ref() {
 | 
					                    if !self.device.poll_readable(cx).is_ready() {
 | 
				
			||||||
                        let mut cx = Context::from_waker(w);
 | 
					 | 
				
			||||||
                        self.device.poll_readable(&mut cx).is_ready()
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        false
 | 
					 | 
				
			||||||
                    };
 | 
					 | 
				
			||||||
                    if !ready {
 | 
					 | 
				
			||||||
                        return None;
 | 
					                        return None;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -181,28 +164,10 @@ impl Device for TunTapDevice {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn register_waker(&mut self, w: &Waker) {
 | 
					    fn transmit(&mut self, _cx: &mut Context) -> Option<Self::TxToken<'_>> {
 | 
				
			||||||
        match self.waker {
 | 
					        Some(TxToken {
 | 
				
			||||||
            // Optimization: If both the old and new Wakers wake the same task, we can simply
 | 
					            device: &mut self.device,
 | 
				
			||||||
            // keep the old waker, skipping the clone. (In most executor implementations,
 | 
					        })
 | 
				
			||||||
            // cloning a waker is somewhat expensive, comparable to cloning an Arc).
 | 
					 | 
				
			||||||
            Some(ref w2) if (w2.will_wake(w)) => {}
 | 
					 | 
				
			||||||
            _ => {
 | 
					 | 
				
			||||||
                // clone the new waker and store it
 | 
					 | 
				
			||||||
                if let Some(old_waker) = core::mem::replace(&mut self.waker, Some(w.clone())) {
 | 
					 | 
				
			||||||
                    // We had a waker registered for another task. Wake it, so the other task can
 | 
					 | 
				
			||||||
                    // reregister itself if it's still interested.
 | 
					 | 
				
			||||||
                    //
 | 
					 | 
				
			||||||
                    // If two tasks are waiting on the same thing concurrently, this will cause them
 | 
					 | 
				
			||||||
                    // to wake each other in a loop fighting over this WakerRegistration. This wastes
 | 
					 | 
				
			||||||
                    // CPU but things will still work.
 | 
					 | 
				
			||||||
                    //
 | 
					 | 
				
			||||||
                    // If the user wants to have two tasks waiting on the same thing they should use
 | 
					 | 
				
			||||||
                    // a more appropriate primitive that can store multiple wakers.
 | 
					 | 
				
			||||||
                    old_waker.wake()
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn capabilities(&self) -> DeviceCapabilities {
 | 
					    fn capabilities(&self) -> DeviceCapabilities {
 | 
				
			||||||
@ -211,7 +176,7 @@ impl Device for TunTapDevice {
 | 
				
			|||||||
        caps
 | 
					        caps
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn link_state(&mut self) -> LinkState {
 | 
					    fn link_state(&mut self, _cx: &mut Context) -> LinkState {
 | 
				
			||||||
        LinkState::Up
 | 
					        LinkState::Up
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -219,3 +184,41 @@ impl Device for TunTapDevice {
 | 
				
			|||||||
        [0x02, 0x03, 0x04, 0x05, 0x06, 0x07]
 | 
					        [0x02, 0x03, 0x04, 0x05, 0x06, 0x07]
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[doc(hidden)]
 | 
				
			||||||
 | 
					pub struct RxToken {
 | 
				
			||||||
 | 
					    buffer: Vec<u8>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl device::RxToken for RxToken {
 | 
				
			||||||
 | 
					    fn consume<R, F>(mut self, f: F) -> R
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        F: FnOnce(&mut [u8]) -> R,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        f(&mut self.buffer)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[doc(hidden)]
 | 
				
			||||||
 | 
					pub struct TxToken<'a> {
 | 
				
			||||||
 | 
					    device: &'a mut Async<TunTap>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'a> device::TxToken for TxToken<'a> {
 | 
				
			||||||
 | 
					    fn consume<R, F>(self, len: usize, f: F) -> R
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        F: FnOnce(&mut [u8]) -> R,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        let mut buffer = vec![0; len];
 | 
				
			||||||
 | 
					        let result = f(&mut buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // todo handle WouldBlock with async
 | 
				
			||||||
 | 
					        match self.device.get_mut().write(&buffer) {
 | 
				
			||||||
 | 
					            Ok(_) => {}
 | 
				
			||||||
 | 
					            Err(e) if e.kind() == io::ErrorKind::WouldBlock => info!("transmit WouldBlock"),
 | 
				
			||||||
 | 
					            Err(e) => panic!("transmit error: {:?}", e),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        result
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user