code: func (f *FIFO) Pop(process PopProcessFunc) (interface{}, error) {
  	f.lock.Lock()
  	defer f.lock.Unlock()
  	for {
  		for len(f.queue) == 0 {
  			// When the queue is empty, invocation of Pop() is blocked until new item is enqueued.
  			// When Close() is called, the f.closed is set and the condition is broadcasted.
  			// Which causes this loop to continue and return from the Pop().
  			if f.IsClosed() {
  				return nil, FIFOClosedError
  			}
  
  			f.cond.Wait()
  		}
  		id := f.queue[0]
  		f.queue = f.queue[1:]
  		if f.initialPopulationCount > 0 {
  			f.initialPopulationCount--
  		}
  		item, ok := f.items[id]
  		if !ok {
  			// Item may have been deleted subsequently.
  			continue
  		}
  		delete(f.items, id)
  		err := process(item)
  		if e, ok := err.(ErrRequeue); ok {
  			f.addIfNotPresent(id, item)
  			err = e.Err
  		}
  		return item, err
  	}
  }
docs: // Pop waits until an item is ready and processes it. If multiple items are
  // ready, they are returned in the order in which they were added/updated.
  // The item is removed from the queue (and the store) before it is processed,
  // so if you don't successfully process it, it should be added back with
  // AddIfNotPresent(). process function is called under lock, so it is safe
  // update data structures in it that need to be in sync with the queue.