@@ -33,6 +33,8 @@ pub struct UdpFramed<C> {
3333 wr : BytesMut ,
3434 out_addr : SocketAddr ,
3535 flushed : bool ,
36+ is_readable : bool ,
37+ current_addr : Option < SocketAddr > ,
3638}
3739
3840impl < C : Decoder > Stream for UdpFramed < C > {
@@ -42,19 +44,37 @@ impl<C: Decoder> Stream for UdpFramed<C> {
4244 fn poll ( & mut self ) -> Poll < Option < ( Self :: Item ) > , Self :: Error > {
4345 self . rd . reserve ( INITIAL_RD_CAPACITY ) ;
4446
45- let ( n, addr) = unsafe {
46- // Read into the buffer without having to initialize the memory.
47- let ( n, addr) = try_ready ! ( self . socket. poll_recv_from( self . rd. bytes_mut( ) ) ) ;
48- self . rd . advance_mut ( n) ;
49- ( n, addr)
50- } ;
51- trace ! ( "received {} bytes, decoding" , n) ;
52- let frame_res = self . codec . decode ( & mut self . rd ) ;
53- self . rd . clear ( ) ;
54- let frame = frame_res?;
55- let result = frame. map ( |frame| ( frame, addr) ) ; // frame -> (frame, addr)
56- trace ! ( "frame decoded from buffer" ) ;
57- Ok ( Async :: Ready ( result) )
47+ loop {
48+ // Are there are still bytes left in the read buffer to decode?
49+ if self . is_readable {
50+ if let Some ( frame) = self . codec . decode ( & mut self . rd ) ? {
51+ trace ! ( "frame decoded from buffer" ) ;
52+
53+ let current_addr = self
54+ . current_addr
55+ . expect ( "will always be set before this line is called" ) ;
56+
57+ return Ok ( Async :: Ready ( Some ( ( frame, current_addr) ) ) ) ;
58+ }
59+
60+ // if this line has been reached then decode has returned `None`.
61+ self . is_readable = false ;
62+ self . rd . clear ( ) ;
63+ }
64+
65+ // We're out of data. Try and fetch more data to decode
66+ let ( n, addr) = unsafe {
67+ // Read into the buffer without having to initialize the memory.
68+ let ( n, addr) = try_ready ! ( self . socket. poll_recv_from( self . rd. bytes_mut( ) ) ) ;
69+ self . rd . advance_mut ( n) ;
70+ ( n, addr)
71+ } ;
72+
73+ self . current_addr = Some ( addr) ;
74+ self . is_readable = true ;
75+
76+ trace ! ( "received {} bytes, decoding" , n) ;
77+ }
5878 }
5979}
6080
@@ -126,6 +146,8 @@ impl<C> UdpFramed<C> {
126146 rd : BytesMut :: with_capacity ( INITIAL_RD_CAPACITY ) ,
127147 wr : BytesMut :: with_capacity ( INITIAL_WR_CAPACITY ) ,
128148 flushed : true ,
149+ is_readable : false ,
150+ current_addr : None ,
129151 }
130152 }
131153
0 commit comments