code: func (rb *RingBuffer) Poll(timeout time.Duration) (interface{}, error) {
  	var (
  		n     *node
  		pos   = atomic.LoadUint64(&rb.dequeue)
  		start time.Time
  	)
  	if timeout > 0 {
  		start = time.Now()
  	}
  L:
  	for {
  		if atomic.LoadUint64(&rb.disposed) == 1 {
  			return nil, ErrDisposed
  		}
  
  		n = rb.nodes[pos&rb.mask]
  		seq := atomic.LoadUint64(&n.position)
  		switch dif := seq - (pos + 1); {
  		case dif == 0:
  			if atomic.CompareAndSwapUint64(&rb.dequeue, pos, pos+1) {
  				break L
  			}
  		case dif < 0:
  			panic(`Ring buffer in compromised state during a get operation.`)
  		default:
  			pos = atomic.LoadUint64(&rb.dequeue)
  		}
  
  		if timeout > 0 && time.Since(start) >= timeout {
  			return nil, ErrTimeout
  		}
  
  		runtime.Gosched() // free up the cpu before the next iteration
  	}
  	data := n.data
  	n.data = nil
  	atomic.StoreUint64(&n.position, pos+rb.mask+1)
  	return data, nil
  }
docs: // Poll will return the next item in the queue.  This call will block
  // if the queue is empty.  This call will unblock when an item is added
  // to the queue, Dispose is called on the queue, or the timeout is reached. An
  // error will be returned if the queue is disposed or a timeout occurs. A
  // non-positive timeout will block indefinitely.