code: func (s *Semaphore) monitorLock(session string, stopCh chan struct{}) {
  	defer close(stopCh)
  	kv := s.c.KV()
  	opts := &QueryOptions{RequireConsistent: true}
  WAIT:
  	retries := s.opts.MonitorRetries
  RETRY:
  	pairs, meta, err := kv.List(s.opts.Prefix, opts)
  	if err != nil {
  		// If configured we can try to ride out a brief Consul unavailability
  		// by doing retries. Note that we have to attempt the retry in a non-
  		// blocking fashion so that we have a clean place to reset the retry
  		// counter if service is restored.
  		if retries > 0 && IsRetryableError(err) {
  			time.Sleep(s.opts.MonitorRetryTime)
  			retries--
  			opts.WaitIndex = 0
  			goto RETRY
  		}
  		return
  	}
  	lockPair := s.findLock(pairs)
  	lock, err := s.decodeLock(lockPair)
  	if err != nil {
  		return
  	}
  	s.pruneDeadHolders(lock, pairs)
  	if _, ok := lock.Holders[session]; ok {
  		opts.WaitIndex = meta.LastIndex
  		goto WAIT
  	}
  }
docs: // monitorLock is a long running routine to monitor a semaphore ownership
  // It closes the stopCh if we lose our slot.