code: func (s *Stream) Read(b []byte) (n int, err error) {
  	defer asyncNotify(s.recvNotifyCh)
  START:
  	s.stateLock.Lock()
  	switch s.state {
  	case streamLocalClose:
  		fallthrough
  	case streamRemoteClose:
  		fallthrough
  	case streamClosed:
  		s.recvLock.Lock()
  		if s.recvBuf == nil || s.recvBuf.Len() == 0 {
  			s.recvLock.Unlock()
  			s.stateLock.Unlock()
  			return 0, io.EOF
  		}
  		s.recvLock.Unlock()
  	case streamReset:
  		s.stateLock.Unlock()
  		return 0, ErrConnectionReset
  	}
  	s.stateLock.Unlock()
  
  	// If there is no data available, block
  	s.recvLock.Lock()
  	if s.recvBuf == nil || s.recvBuf.Len() == 0 {
  		s.recvLock.Unlock()
  		goto WAIT
  	}
  
  	// Read any bytes
  	n, _ = s.recvBuf.Read(b)
  	s.recvLock.Unlock()
  
  	// Send a window update potentially
  	err = s.sendWindowUpdate()
  	return n, err
  
  WAIT:
  	var timeout <-chan time.Time
  	var timer *time.Timer
  	readDeadline := s.readDeadline.Load().(time.Time)
  	if !readDeadline.IsZero() {
  		delay := readDeadline.Sub(time.Now())
  		timer = time.NewTimer(delay)
  		timeout = timer.C
  	}
  	select {
  	case <-s.recvNotifyCh:
  		if timer != nil {
  			timer.Stop()
  		}
  		goto START
  	case <-timeout:
  		return 0, ErrTimeout
  	}
  }
docs: // Read is used to read from the stream