|  | @@ -396,6 +396,13 @@ impl Interface {
 | 
	
		
			
				|  |  |      /// This function returns a boolean value indicating whether any packets were
 | 
	
		
			
				|  |  |      /// processed or emitted, and thus, whether the readiness of any socket might
 | 
	
		
			
				|  |  |      /// have changed.
 | 
	
		
			
				|  |  | +    ///
 | 
	
		
			
				|  |  | +    /// # Note
 | 
	
		
			
				|  |  | +    /// This function performs a bounded amount of work per call to avoid
 | 
	
		
			
				|  |  | +    /// starving other tasks of CPU time. If it returns true, there may still be
 | 
	
		
			
				|  |  | +    /// packets to be received or transmitted. Depending on system design,
 | 
	
		
			
				|  |  | +    /// calling this function in a loop may cause a denial of service if
 | 
	
		
			
				|  |  | +    /// packets cannot be processed faster than they arrive.
 | 
	
		
			
				|  |  |      pub fn poll<D>(
 | 
	
		
			
				|  |  |          &mut self,
 | 
	
		
			
				|  |  |          timestamp: Instant,
 | 
	
	
		
			
				|  | @@ -429,23 +436,12 @@ impl Interface {
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        let mut readiness_may_have_changed = false;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        loop {
 | 
	
		
			
				|  |  | -            let mut did_something = false;
 | 
	
		
			
				|  |  | -            did_something |= self.socket_ingress(device, sockets);
 | 
	
		
			
				|  |  | -            did_something |= self.socket_egress(device, sockets);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            #[cfg(feature = "proto-igmp")]
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                did_something |= self.igmp_egress(device);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | +        let mut readiness_may_have_changed = self.socket_ingress(device, sockets);
 | 
	
		
			
				|  |  | +        readiness_may_have_changed |= self.socket_egress(device, sockets);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            if did_something {
 | 
	
		
			
				|  |  | -                readiness_may_have_changed = true;
 | 
	
		
			
				|  |  | -            } else {
 | 
	
		
			
				|  |  | -                break;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | +        #[cfg(feature = "proto-igmp")]
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            readiness_may_have_changed |= self.igmp_egress(device);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          readiness_may_have_changed
 | 
	
	
		
			
				|  | @@ -507,67 +503,65 @@ impl Interface {
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          let mut processed_any = false;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        while let Some((rx_token, tx_token)) = device.receive(self.inner.now) {
 | 
	
		
			
				|  |  | -            let rx_meta = rx_token.meta();
 | 
	
		
			
				|  |  | -            rx_token.consume(|frame| {
 | 
	
		
			
				|  |  | -                if frame.is_empty() {
 | 
	
		
			
				|  |  | -                    return;
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | +        let Some((rx_token, tx_token)) = device.receive(self.inner.now) else {
 | 
	
		
			
				|  |  | +            return processed_any;
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                match self.inner.caps.medium {
 | 
	
		
			
				|  |  | -                    #[cfg(feature = "medium-ethernet")]
 | 
	
		
			
				|  |  | -                    Medium::Ethernet => {
 | 
	
		
			
				|  |  | -                        if let Some(packet) = self.inner.process_ethernet(
 | 
	
		
			
				|  |  | -                            sockets,
 | 
	
		
			
				|  |  | -                            rx_meta,
 | 
	
		
			
				|  |  | -                            frame,
 | 
	
		
			
				|  |  | -                            &mut self.fragments,
 | 
	
		
			
				|  |  | -                        ) {
 | 
	
		
			
				|  |  | -                            if let Err(err) =
 | 
	
		
			
				|  |  | -                                self.inner.dispatch(tx_token, packet, &mut self.fragmenter)
 | 
	
		
			
				|  |  | -                            {
 | 
	
		
			
				|  |  | -                                net_debug!("Failed to send response: {:?}", err);
 | 
	
		
			
				|  |  | -                            }
 | 
	
		
			
				|  |  | +        let rx_meta = rx_token.meta();
 | 
	
		
			
				|  |  | +        rx_token.consume(|frame| {
 | 
	
		
			
				|  |  | +            if frame.is_empty() {
 | 
	
		
			
				|  |  | +                return;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            match self.inner.caps.medium {
 | 
	
		
			
				|  |  | +                #[cfg(feature = "medium-ethernet")]
 | 
	
		
			
				|  |  | +                Medium::Ethernet => {
 | 
	
		
			
				|  |  | +                    if let Some(packet) =
 | 
	
		
			
				|  |  | +                        self.inner
 | 
	
		
			
				|  |  | +                            .process_ethernet(sockets, rx_meta, frame, &mut self.fragments)
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  | +                        if let Err(err) =
 | 
	
		
			
				|  |  | +                            self.inner.dispatch(tx_token, packet, &mut self.fragmenter)
 | 
	
		
			
				|  |  | +                        {
 | 
	
		
			
				|  |  | +                            net_debug!("Failed to send response: {:?}", err);
 | 
	
		
			
				|  |  |                          }
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  | -                    #[cfg(feature = "medium-ip")]
 | 
	
		
			
				|  |  | -                    Medium::Ip => {
 | 
	
		
			
				|  |  | -                        if let Some(packet) =
 | 
	
		
			
				|  |  | -                            self.inner
 | 
	
		
			
				|  |  | -                                .process_ip(sockets, rx_meta, frame, &mut self.fragments)
 | 
	
		
			
				|  |  | -                        {
 | 
	
		
			
				|  |  | -                            if let Err(err) = self.inner.dispatch_ip(
 | 
	
		
			
				|  |  | -                                tx_token,
 | 
	
		
			
				|  |  | -                                PacketMeta::default(),
 | 
	
		
			
				|  |  | -                                packet,
 | 
	
		
			
				|  |  | -                                &mut self.fragmenter,
 | 
	
		
			
				|  |  | -                            ) {
 | 
	
		
			
				|  |  | -                                net_debug!("Failed to send response: {:?}", err);
 | 
	
		
			
				|  |  | -                            }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                #[cfg(feature = "medium-ip")]
 | 
	
		
			
				|  |  | +                Medium::Ip => {
 | 
	
		
			
				|  |  | +                    if let Some(packet) =
 | 
	
		
			
				|  |  | +                        self.inner
 | 
	
		
			
				|  |  | +                            .process_ip(sockets, rx_meta, frame, &mut self.fragments)
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  | +                        if let Err(err) = self.inner.dispatch_ip(
 | 
	
		
			
				|  |  | +                            tx_token,
 | 
	
		
			
				|  |  | +                            PacketMeta::default(),
 | 
	
		
			
				|  |  | +                            packet,
 | 
	
		
			
				|  |  | +                            &mut self.fragmenter,
 | 
	
		
			
				|  |  | +                        ) {
 | 
	
		
			
				|  |  | +                            net_debug!("Failed to send response: {:?}", err);
 | 
	
		
			
				|  |  |                          }
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  | -                    #[cfg(feature = "medium-ieee802154")]
 | 
	
		
			
				|  |  | -                    Medium::Ieee802154 => {
 | 
	
		
			
				|  |  | -                        if let Some(packet) = self.inner.process_ieee802154(
 | 
	
		
			
				|  |  | -                            sockets,
 | 
	
		
			
				|  |  | -                            rx_meta,
 | 
	
		
			
				|  |  | -                            frame,
 | 
	
		
			
				|  |  | -                            &mut self.fragments,
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                #[cfg(feature = "medium-ieee802154")]
 | 
	
		
			
				|  |  | +                Medium::Ieee802154 => {
 | 
	
		
			
				|  |  | +                    if let Some(packet) =
 | 
	
		
			
				|  |  | +                        self.inner
 | 
	
		
			
				|  |  | +                            .process_ieee802154(sockets, rx_meta, frame, &mut self.fragments)
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  | +                        if let Err(err) = self.inner.dispatch_ip(
 | 
	
		
			
				|  |  | +                            tx_token,
 | 
	
		
			
				|  |  | +                            PacketMeta::default(),
 | 
	
		
			
				|  |  | +                            packet,
 | 
	
		
			
				|  |  | +                            &mut self.fragmenter,
 | 
	
		
			
				|  |  |                          ) {
 | 
	
		
			
				|  |  | -                            if let Err(err) = self.inner.dispatch_ip(
 | 
	
		
			
				|  |  | -                                tx_token,
 | 
	
		
			
				|  |  | -                                PacketMeta::default(),
 | 
	
		
			
				|  |  | -                                packet,
 | 
	
		
			
				|  |  | -                                &mut self.fragmenter,
 | 
	
		
			
				|  |  | -                            ) {
 | 
	
		
			
				|  |  | -                                net_debug!("Failed to send response: {:?}", err);
 | 
	
		
			
				|  |  | -                            }
 | 
	
		
			
				|  |  | +                            net_debug!("Failed to send response: {:?}", err);
 | 
	
		
			
				|  |  |                          }
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                processed_any = true;
 | 
	
		
			
				|  |  | -            });
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            processed_any = true;
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          processed_any
 | 
	
		
			
				|  |  |      }
 |