// SeqnoLock acquires a lock on seqno operations.  NewSeqnoProvider calls it.
// After all operations with a seqno provider are done (i.e. fully submitted
// to stellard), then the lock should be released with SeqnoUnlock.
420241
func (w *WalletState) SeqnoLock() {
	w.seqnoMu.Lock()
	w.Lock()
	w.seqnoLockHeld = true
	w.Unlock()
}
437408
func (mutex *Mutex) Lock() error {
	ret := int(C.SDL_LockMutex(mutex.cptr()))
	if ret != 0 {
		return GetError()
	}
	return nil
}
965790
func (rw *BoundedRWLock) RUnlock() {
	rw.control.Lock()
	rw.readers--
	if rw.readers == 0 {
		rw.processQueue()
	}
	rw.control.Unlock()
}
1147841
func (c *DialContext) NextSeq(db string, collection string, id string) (int, error) {
	s := c.Ref()
	defer c.UnRef(s)

	var res struct {
		Seq int
	}
	_, err := s.DB(db).C(collection).FindId(id).Apply(mgo.Change{
		Update:    bson.M{"$inc": bson.M{"seq": 1}},
		ReturnNew: true,
	}, &res)

	return res.Seq, err
}
1063521
func (s *State) Lock(info *state.LockInfo) (string, error) {
	s.mu.Lock()
	defer s.mu.Unlock()

	if s.disableLocks {
		return "", nil
	}

	if c, ok := s.Client.(ClientLocker); ok {
		return c.Lock(info)
	}
	return "", nil
}
1163858
func (ctl *HandshakeController) releaseKeyNoLock(symkeyid string, topic *Topic) bool {
	if ctl.symKeyIndex[symkeyid] == nil {
		log.Debug("no symkey", "symkeyid", symkeyid)
		return false
	}
	ctl.symKeyIndex[symkeyid].expiredAt = time.Now()
	log.Debug("handshake release", "symkeyid", symkeyid)
	return true
}
314375
func (ss *SQLSubStore) addSeq(subid, seqno uint64) bool {
	ap := ss.getOrCreateAcksPending(subid, seqno)
	ap.msgs[seqno] = struct{}{}
	return len(ap.msgs) >= sqlMaxPendingAcks
}
452581
func (r *HashRing) copyServersNoLock() []string {
	servers := make([]string, 0, len(r.serverSet))
	for server := range r.serverSet {
		servers = append(servers, server)
	}
	return servers
}
629046
func (m *Mutex) Lock() error {
	value, err := m.genValueFunc()
	if err != nil {
		return err
	}

	for i := 0; i < m.tries; i++ {
		if i != 0 {
			time.Sleep(m.delayFunc(i))
		}

		start := time.Now()

		n := m.actOnPoolsAsync(func(pool Pool) bool {
			return m.acquire(pool, value)
		})

		until := time.Now().Add(m.expiry - time.Now().Sub(start) - time.Duration(int64(float64(m.expiry)*m.factor)) + 2*time.Millisecond)
		if n >= m.quorum && time.Now().Before(until) {
			m.value = value
			m.until = until
			return nil
		}
		m.actOnPoolsAsync(func(pool Pool) bool {
			return m.release(pool, value)
		})
	}

	return ErrFailed
}
808922
func lock(ds *Dsync, locks *[]string, lockName, id, source string, isReadLock bool) bool {

	// Create buffered channel of size equal to total number of nodes.
	ch := make(chan Granted, ds.dNodeCount)
	defer close(ch)

	var wg sync.WaitGroup
	for index, c := range ds.rpcClnts {

		wg.Add(1)
		// broadcast lock request to all nodes
		go func(index int, isReadLock bool, c NetLocker) {
			defer wg.Done()

			args := LockArgs{
				UID:             id,
				Resource:        lockName,
				ServerAddr:      ds.rpcClnts[ds.ownNode].ServerAddr(),
				ServiceEndpoint: ds.rpcClnts[ds.ownNode].ServiceEndpoint(),
				Source:          source,
			}

			var locked bool
			var err error
			if isReadLock {
				if locked, err = c.RLock(args); err != nil {
					log("Unable to call RLock", err)
				}
			} else {
				if locked, err = c.Lock(args); err != nil {
					log("Unable to call Lock", err)
				}
			}

			g := Granted{index: index}
			if locked {
				g.lockUID = args.UID
			}

			ch <- g

		}(index, isReadLock, c)
	}

	quorum := false

	wg.Add(1)
	go func(isReadLock bool) {

		// Wait until we have either
		//
		// a) received all lock responses
		// b) received too many 'non-'locks for quorum to be still possible
		// c) time out
		//
		i, locksFailed := 0, 0
		done := false
		timeout := time.After(DRWMutexAcquireTimeout)

		for ; i < ds.dNodeCount; i++ { // Loop until we acquired all locks

			select {
			case grant := <-ch:
				if grant.isLocked() {
					// Mark that this node has acquired the lock
					(*locks)[grant.index] = grant.lockUID
				} else {
					locksFailed++
					if !isReadLock && locksFailed > ds.dNodeCount-ds.dquorum ||
						isReadLock && locksFailed > ds.dNodeCount-ds.dquorumReads {
						// We know that we are not going to get the lock anymore,
						// so exit out and release any locks that did get acquired
						done = true
						// Increment the number of grants received from the buffered channel.
						i++
						releaseAll(ds, locks, lockName, isReadLock)
					}
				}
			case <-timeout:
				done = true
				// timeout happened, maybe one of the nodes is slow, count
				// number of locks to check whether we have quorum or not
				if !quorumMet(locks, isReadLock, ds.dquorum, ds.dquorumReads) {
					releaseAll(ds, locks, lockName, isReadLock)
				}
			}

			if done {
				break
			}
		}

		// Count locks in order to determine whether we have quorum or not
		quorum = quorumMet(locks, isReadLock, ds.dquorum, ds.dquorumReads)

		// Signal that we have the quorum
		wg.Done()

		// Wait for the other responses and immediately release the locks
		// (do not add them to the locks array because the DRWMutex could
		//  already has been unlocked again by the original calling thread)
		for ; i < ds.dNodeCount; i++ {
			grantToBeReleased := <-ch
			if grantToBeReleased.isLocked() {
				// release lock
				sendRelease(ds, ds.rpcClnts[grantToBeReleased.index], lockName, grantToBeReleased.lockUID, isReadLock)
			}
		}
	}(isReadLock)

	wg.Wait()

	// Verify that localhost server is actively participating in the lock (the lock maintenance relies on this fact)
	if quorum && !isLocked((*locks)[ds.ownNode]) {
		// If not, release lock (and try again later)
		releaseAll(ds, locks, lockName, isReadLock)
		quorum = false
	}

	return quorum
}
730113
func (m *MutexKV) Lock(key string) {
	log.Printf("[DEBUG] Locking %q", key)
	m.get(key).Lock()
	log.Printf("[DEBUG] Locked %q", key)
}
827593
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
	}
}
1239551
func (client *lockRESTClient) Unlock(args dsync.LockArgs) (reply bool, err error) {
	return client.restCall(lockRESTMethodUnlock, args)
}
176632
func (li *localLockInstance) RUnlock() {
	readLock := true
	li.ns.unlock(li.volume, li.path, li.opsID, readLock)
}
98927
func NewClaimSeqnoProvider(mctx libkb.MetaContext, walletState *WalletState) (seqnoProvider *ClaimSeqnoProvider, unlock func()) {
	walletState.SeqnoLock()
	return &ClaimSeqnoProvider{
		mctx:        mctx,
		walletState: walletState,
	}, walletState.SeqnoUnlock
}
958196
func randSeqno(lo keybase1.Seqno, hi keybase1.Seqno) (keybase1.Seqno, error) {
	rangeBig := big.NewInt(int64(hi - lo + 1))
	n, err := rand.Int(rand.Reader, rangeBig)
	if err != nil {
		return keybase1.Seqno(0), err
	}
	return keybase1.Seqno(n.Int64()) + lo, nil
}
141736
func (a *AccountState) ForceSeqnoRefresh(mctx libkb.MetaContext) error {
	seqno, err := a.remoter.AccountSeqno(mctx.Ctx(), a.accountID)
	if err != nil {
		return err
	}

	a.Lock()
	defer a.Unlock()

	if seqno == a.seqno {
		mctx.Debug("ForceSeqnoRefresh did not update AccountState for %s (existing: %d, remote: %d)", a.accountID, a.seqno, seqno)
		return nil
	}

	if seqno > a.seqno {
		// if network is greater than cached, then update
		mctx.Debug("ForceSeqnoRefresh updated seqno for %s: %d => %d", a.accountID, a.seqno, seqno)
		a.seqno = seqno
		return nil
	}

	// delete any stale pending tx (in case missed notification somehow)
	for k, v := range a.pendingTxs {
		age := time.Since(v.ctime)
		if age > 30*time.Second {
			mctx.Debug("ForceSeqnoRefresh removing pending tx %s due to old age (%s)", k, age)
			delete(a.pendingTxs, k)
		}
	}

	// delete any stale inuse seqnos (in case missed notification somehow)
	for k, v := range a.inuseSeqnos {
		if seqno > k {
			mctx.Debug("ForceSeqnoRefresh removing inuse seqno %d due to network seqno > to it (%s)", k, seqno)
			delete(a.inuseSeqnos, k)
		}
		age := time.Since(v.ctime)
		if age > 30*time.Second {
			mctx.Debug("ForceSeqnoRefresh removing inuse seqno %d due to old age (%s)", k, age)
			delete(a.inuseSeqnos, k)
		}
	}

	if len(a.pendingTxs) == 0 && len(a.inuseSeqnos) == 0 {
		// if no pending tx or inuse seqnos, then network should be correct
		mctx.Debug("ForceSeqnoRefresh corrected seqno for %s: %d => %d", a.accountID, a.seqno, seqno)
		a.seqno = seqno
		return nil
	}

	mctx.Debug("ForceSeqnoRefresh did not update AccountState for %s due to pending tx/seqnos (existing: %d, remote: %d, pending txs: %d, inuse seqnos: %d)", a.accountID, a.seqno, seqno, len(a.pendingTxs), len(a.inuseSeqnos))

	return nil
}