@@ -396,6 +396,13 @@ impl Interface {
396396 /// This function returns a boolean value indicating whether any packets were
397397 /// processed or emitted, and thus, whether the readiness of any socket might
398398 /// have changed.
399+ ///
400+ /// # Note
401+ /// This function performs a bounded amount of work per call to avoid
402+ /// starving other tasks of CPU time. If it returns true, there may still be
403+ /// packets to be received or transmitted. Depending on system design,
404+ /// calling this function in a loop may cause a denial of service if
405+ /// packets cannot be processed faster than they arrive.
399406 pub fn poll < D > (
400407 & mut self ,
401408 timestamp : Instant ,
@@ -429,23 +436,12 @@ impl Interface {
429436 }
430437 }
431438
432- let mut readiness_may_have_changed = false ;
433-
434- loop {
435- let mut did_something = false ;
436- did_something |= self . socket_ingress ( device, sockets) ;
437- did_something |= self . socket_egress ( device, sockets) ;
438-
439- #[ cfg( feature = "proto-igmp" ) ]
440- {
441- did_something |= self . igmp_egress ( device) ;
442- }
439+ let mut readiness_may_have_changed = self . socket_ingress ( device, sockets) ;
440+ readiness_may_have_changed |= self . socket_egress ( device, sockets) ;
443441
444- if did_something {
445- readiness_may_have_changed = true ;
446- } else {
447- break ;
448- }
442+ #[ cfg( feature = "proto-igmp" ) ]
443+ {
444+ readiness_may_have_changed |= self . igmp_egress ( device) ;
449445 }
450446
451447 readiness_may_have_changed
@@ -507,67 +503,65 @@ impl Interface {
507503 {
508504 let mut processed_any = false ;
509505
510- while let Some ( ( rx_token, tx_token) ) = device. receive ( self . inner . now ) {
511- let rx_meta = rx_token. meta ( ) ;
512- rx_token. consume ( |frame| {
513- if frame. is_empty ( ) {
514- return ;
515- }
506+ let Some ( ( rx_token, tx_token) ) = device. receive ( self . inner . now ) else {
507+ return processed_any;
508+ } ;
516509
517- match self . inner . caps . medium {
518- #[ cfg( feature = "medium-ethernet" ) ]
519- Medium :: Ethernet => {
520- if let Some ( packet) = self . inner . process_ethernet (
521- sockets,
522- rx_meta,
523- frame,
524- & mut self . fragments ,
525- ) {
526- if let Err ( err) =
527- self . inner . dispatch ( tx_token, packet, & mut self . fragmenter )
528- {
529- net_debug ! ( "Failed to send response: {:?}" , err) ;
530- }
510+ let rx_meta = rx_token. meta ( ) ;
511+ rx_token. consume ( |frame| {
512+ if frame. is_empty ( ) {
513+ return ;
514+ }
515+
516+ match self . inner . caps . medium {
517+ #[ cfg( feature = "medium-ethernet" ) ]
518+ Medium :: Ethernet => {
519+ if let Some ( packet) =
520+ self . inner
521+ . process_ethernet ( sockets, rx_meta, frame, & mut self . fragments )
522+ {
523+ if let Err ( err) =
524+ self . inner . dispatch ( tx_token, packet, & mut self . fragmenter )
525+ {
526+ net_debug ! ( "Failed to send response: {:?}" , err) ;
531527 }
532528 }
533- # [ cfg ( feature = "medium-ip" ) ]
534- Medium :: Ip => {
535- if let Some ( packet ) =
536- self . inner
537- . process_ip ( sockets , rx_meta , frame , & mut self . fragments )
538- {
539- if let Err ( err ) = self . inner . dispatch_ip (
540- tx_token ,
541- PacketMeta :: default ( ) ,
542- packet ,
543- & mut self . fragmenter ,
544- ) {
545- net_debug ! ( "Failed to send response: {:?}" , err ) ;
546- }
529+ }
530+ # [ cfg ( feature = "medium-ip" ) ]
531+ Medium :: Ip => {
532+ if let Some ( packet ) =
533+ self . inner
534+ . process_ip ( sockets , rx_meta , frame , & mut self . fragments )
535+ {
536+ if let Err ( err ) = self . inner . dispatch_ip (
537+ tx_token ,
538+ PacketMeta :: default ( ) ,
539+ packet ,
540+ & mut self . fragmenter ,
541+ ) {
542+ net_debug ! ( "Failed to send response: {:?}" , err ) ;
547543 }
548544 }
549- #[ cfg( feature = "medium-ieee802154" ) ]
550- Medium :: Ieee802154 => {
551- if let Some ( packet) = self . inner . process_ieee802154 (
552- sockets,
553- rx_meta,
554- frame,
555- & mut self . fragments ,
545+ }
546+ #[ cfg( feature = "medium-ieee802154" ) ]
547+ Medium :: Ieee802154 => {
548+ if let Some ( packet) =
549+ self . inner
550+ . process_ieee802154 ( sockets, rx_meta, frame, & mut self . fragments )
551+ {
552+ if let Err ( err) = self . inner . dispatch_ip (
553+ tx_token,
554+ PacketMeta :: default ( ) ,
555+ packet,
556+ & mut self . fragmenter ,
556557 ) {
557- if let Err ( err) = self . inner . dispatch_ip (
558- tx_token,
559- PacketMeta :: default ( ) ,
560- packet,
561- & mut self . fragmenter ,
562- ) {
563- net_debug ! ( "Failed to send response: {:?}" , err) ;
564- }
558+ net_debug ! ( "Failed to send response: {:?}" , err) ;
565559 }
566560 }
567561 }
568- processed_any = true ;
569- } ) ;
570- }
562+ }
563+ processed_any = true ;
564+ } ) ;
571565
572566 processed_any
573567 }
0 commit comments