// Called with e.Mutex UNlocked
505054
func (e *Endpoint) regenerate(owner Owner, context *regenerationContext) (retErr error) {
	var revision uint64
	var compilationExecuted bool
	var err error

	context.Stats = regenerationStatistics{}
	stats := &context.Stats
	metrics.EndpointCountRegenerating.Inc()
	stats.totalTime.Start()
	e.getLogger().WithFields(logrus.Fields{
		logfields.StartTime: time.Now(),
		logfields.Reason:    context.Reason,
	}).Debug("Regenerating endpoint")

	defer e.updateRegenerationStatistics(context, retErr)

	e.BuildMutex.Lock()
	defer e.BuildMutex.Unlock()

	stats.waitingForLock.Start()
	// Check if endpoints is still alive before doing any build
	err = e.LockAlive()
	stats.waitingForLock.End(err == nil)
	if err != nil {
		return err
	}

	// When building the initial drop policy in waiting-for-identity state
	// the state remains unchanged
	//
	// GH-5350: Remove this special case to require checking for StateWaitingForIdentity
	if e.GetStateLocked() != StateWaitingForIdentity &&
		!e.BuilderSetStateLocked(StateRegenerating, "Regenerating endpoint: "+context.Reason) {
		e.getLogger().WithField(logfields.EndpointState, e.state).Debug("Skipping build due to invalid state")
		e.Unlock()

		return fmt.Errorf("Skipping build due to invalid state: %s", e.state)
	}

	e.Unlock()

	stats.prepareBuild.Start()
	origDir := e.StateDirectoryPath()
	context.datapathRegenerationContext.currentDir = origDir

	// This is the temporary directory to store the generated headers,
	// the original existing directory is not overwritten until the
	// entire generation process has succeeded.
	tmpDir := e.NextDirectoryPath()
	context.datapathRegenerationContext.nextDir = tmpDir

	// Remove an eventual existing temporary directory that has been left
	// over to make sure we can start the build from scratch
	if err := e.removeDirectory(tmpDir); err != nil && !os.IsNotExist(err) {
		stats.prepareBuild.End(false)
		return fmt.Errorf("unable to remove old temporary directory: %s", err)
	}

	// Create temporary endpoint directory if it does not exist yet
	if err := os.MkdirAll(tmpDir, 0777); err != nil {
		stats.prepareBuild.End(false)
		return fmt.Errorf("Failed to create endpoint directory: %s", err)
	}

	stats.prepareBuild.End(true)

	defer func() {
		if err := e.LockAlive(); err != nil {
			if retErr == nil {
				retErr = err
			} else {
				e.LogDisconnectedMutexAction(err, "after regenerate")
			}
			return
		}

		// Guarntee removal of temporary directory regardless of outcome of
		// build. If the build was successful, the temporary directory will
		// have been moved to a new permanent location. If the build failed,
		// the temporary directory will still exist and we will reomve it.
		e.removeDirectory(tmpDir)

		// Set to Ready, but only if no other changes are pending.
		// State will remain as waiting-to-regenerate if further
		// changes are needed. There should be an another regenerate
		// queued for taking care of it.
		e.BuilderSetStateLocked(StateReady, "Completed endpoint regeneration with no pending regeneration requests")
		e.Unlock()
	}()

	revision, compilationExecuted, err = e.regenerateBPF(owner, context)
	if err != nil {
		failDir := e.FailedDirectoryPath()
		e.getLogger().WithFields(logrus.Fields{
			logfields.Path: failDir,
		}).Warn("generating BPF for endpoint failed, keeping stale directory.")

		// Remove an eventual existing previous failure directory
		e.removeDirectory(failDir)
		os.Rename(tmpDir, failDir)
		return err
	}

	return e.updateRealizedState(stats, origDir, revision, compilationExecuted)
}
1316917
func (m *Mutex) Unlock() bool {
	m.nodem.Lock()
	defer m.nodem.Unlock()

	value := m.value
	if value == "" {
		panic("redsync: unlock of unlocked mutex")
	}

	m.value = ""
	m.until = time.Unix(0, 0)

	n := 0
	for _, node := range m.nodes {
		if node == nil {
			continue
		}

		conn := node.Get()
		status, err := delScript.Do(conn, m.Name, value)
		conn.Close()
		if err != nil {
			continue
		}
		if status == 0 {
			continue
		}
		n++
	}
	if n >= m.Quorum {
		return true
	}
	return false
}
1244212
func (pc *P) WithMutex(key interface{}, fn func()) {
	// Get a lock for this config key, and increment its reference.
	me := pc.getConfigLock(key)
	defer pc.decRef(me, key)

	// Hold this lock's mutex and call "fn".
	me.Lock()
	defer me.Unlock()

	fn()
}
721945
func (l *Lock) Unlock() error {
	return l.store(func(sem *Semaphore) error {
		return sem.Unlock(l.id)
	})
}
1306082
func (c *Mutex) Unlock(id uint64) {
	// Since we are done with all the work for this
	// update, we update the map to reflect that.
	c.mapMtx.Lock()

	mtx, ok := c.mutexes[id]
	if !ok {
		// The mutex not existing in the map means
		// an unlock for an ID not currently locked
		// was attempted.
		panic(fmt.Sprintf("double unlock for id %v",
			id))
	}

	// Decrement the counter. If the count goes to
	// zero, it means this caller was the last one
	// to wait for the mutex, and we can delete it
	// from the map. We can do this safely since we
	// are under the mapMtx, meaning that all other
	// goroutines waiting for the mutex already
	// have incremented it, or will create a new
	// mutex when they get the mapMtx.
	mtx.cnt--
	if mtx.cnt == 0 {
		delete(c.mutexes, id)
	}
	c.mapMtx.Unlock()

	// Unlock the mutex for this ID.
	mtx.Unlock()
}
1086804
func (m LeveledMutex) AssertUnlocked(lockState *LockState) {
	et := lockState.getExclusionType(m.level)
	if et != nonExclusion {
		panic(unexpectedExclusionError{
			levelToString: lockState.levelToString,
			level:         m.level,
			exclusionType: et,
		})
	}
}
3587
func (m *RWMutex) Lock() {
	atomic.AddInt64(&m.pendingWriters, 1)
	m.mutex.Lock()
	atomic.AddInt64(&m.writers, 1)
	atomic.AddInt64(&m.pendingWriters, -1)

	stackBufLen := RWMutexStackBufferLength()

	m.stateMutex.Lock()
	if len(m.stackBuf) < stackBufLen {
		m.stackBuf = make([]byte, stackBufLen)
	}
	n := runtime.Stack(m.stackBuf, false)
	m.lastLockStack = m.stackBuf[:n]
	m.stateMutex.Unlock()
}
96864
func (m *Mutex) Lock() error {
	m.nodem.Lock()
	defer m.nodem.Unlock()

	b := make([]byte, 16)
	_, err := rand.Read(b)
	if err != nil {
		return err
	}
	value := base64.StdEncoding.EncodeToString(b)

	expiry := m.Expiry
	if expiry == 0 {
		expiry = DefaultExpiry
	}

	retries := m.Tries
	if retries == 0 {
		retries = DefaultTries
	}

	for i := 0; i < retries; i++ {
		n := 0
		start := time.Now()
		for _, node := range m.nodes {
			if node == nil {
				continue
			}

			conn := node.Get()
			reply, err := redis.String(conn.Do("set", m.Name, value, "nx", "px", int(expiry/time.Millisecond)))
			conn.Close()
			if err != nil {
				continue
			}
			if reply != "OK" {
				continue
			}
			n++
		}

		factor := m.Factor
		if factor == 0 {
			factor = DefaultFactor
		}

		until := time.Now().Add(expiry - time.Now().Sub(start) - time.Duration(int64(float64(expiry)*factor)) + 2*time.Millisecond)
		if n >= m.Quorum && time.Now().Before(until) {
			m.value = value
			m.until = until
			return nil
		}
		for _, node := range m.nodes {
			if node == nil {
				continue
			}

			conn := node.Get()
			_, err := delScript.Do(conn, m.Name, value)
			conn.Close()
			if err != nil {
				continue
			}
		}

		// Have no delay on the last try so we can return ErrFailed sooner.
		if i == retries-1 {
			continue
		}

		delay := m.Delay
		if delay == 0 {
			delay = DefaultDelay
		}
		time.Sleep(delay)
	}

	return ErrFailed
}
730113
func (m *MutexKV) Lock(key string) {
	log.Printf("[DEBUG] Locking %q", key)
	m.get(key).Lock()
	log.Printf("[DEBUG] Locked %q", key)
}
322054
func (m *Mutex) Unlock(ctx context.Context) error {
	defer m.session.Close()
	// 一定要释放
	return m.mutex.Unlock(ctx)
}
869215
func (m *Mutex) Lock(ctx context.Context) error {
	lockCtx, cancel := context.WithTimeout(ctx, m.timeout)
	defer cancel()
	return m.mutex.Lock(lockCtx)
}
1035417
func (ld *consulLockDescriptor) Unlock(ctx context.Context) error {
	return ld.s.unlock(ctx, ld.lockPath)
}
712978
func (km *keyMutex) getOrCreateLock(id string) *sync.Mutex {
	km.Lock()
	defer km.Unlock()

	if _, exists := km.mutexMap[id]; !exists {
		km.mutexMap[id] = &sync.Mutex{}
	}

	return km.mutexMap[id]
}
1186221
func (l *KeyLock) Unlock() error {
	err := l.keyLock.Unlock()
	if err != nil {
		return err
	}
	return nil
}
127601
func MakeLeveledMutex(level MutexLevel, locker sync.Locker) LeveledMutex {
	return LeveledMutex{
		level:  level,
		locker: locker,
	}
}
908171
func (ld *etcdLockDescriptor) Unlock(ctx context.Context) error {
	_, err := ld.s.cli.Revoke(ctx, ld.leaseID)
	if err != nil {
		return convertError(err, "lease")
	}
	return nil
}
906011
func unlock_notify_callback(argv unsafe.Pointer, argc C.int) {
	for i := 0; i < int(argc); i++ {
		parg := ((*(*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.uint)(nil))]*[1]uint)(argv))[i])
		arg := *parg
		h := arg[0]
		c := unt.get(h)
		c <- struct{}{}
	}
}