//
// S3 Object Lock functions.
//
508563
func readS3ObjectLockConfiguration(conn *s3.S3, bucket string) (interface{}, error) {
	resp, err := retryOnAwsCode(s3.ErrCodeNoSuchBucket, func() (interface{}, error) {
		return conn.GetObjectLockConfiguration(&s3.GetObjectLockConfigurationInput{
			Bucket: aws.String(bucket),
		})
	})
	if err != nil {
		if isAWSErr(err, "ObjectLockConfigurationNotFoundError", "") {
			return nil, nil
		}
		return nil, err
	}

	return flattenS3ObjectLockConfiguration(resp.(*s3.GetObjectLockConfigurationOutput).ObjectLockConfiguration), nil
}
1302765
func (l *LockFile) Lock(timeout time.Duration) error {
	end := time.Now().Add(timeout)
	for {
		if l.TryLock() {
			return nil
		}
		if time.Now().Before(end) {
			time.Sleep(l.resolution)
			continue
		}
		return ErrTimeout
	}

	return fmt.Errorf("not reached")
}
1321944
func (f *LockPIDFile) Lock() (err error) {
	pathp, err := syscall.UTF16PtrFromString(f.name)
	if err != nil {
		return PIDFileLockError{f.name}
	}
	access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE)
	createmode := uint32(syscall.OPEN_ALWAYS)
	sharemode := uint32(syscall.FILE_SHARE_READ) // os.Open always uses FILE_SHARE_READ | FILE_SHARE_WRITE
	var sa *syscall.SecurityAttributes
	r, err := syscall.CreateFile(pathp, access, sharemode, sa, createmode, syscall.FILE_ATTRIBUTE_NORMAL, 0)
	if err != nil {
		return PIDFileLockError{f.name}
	}
	// this is what os.openFile does
	f.file = os.NewFile(uintptr(r), f.name)

	pid := os.Getpid()
	fmt.Fprintf(f.file, "%d", pid)
	f.file.Sync()

	f.G().Log.Debug("Locked pidfile %s for pid=%d", f.name, pid)

	return nil
}
292792
func (r *Registry) WithLock(obj mo.Reference, f func()) {
	if enableLocker {
		mu := r.locker(obj)
		mu.Lock()
		defer mu.Unlock()
	}
	f()
}
493355
func (dm *DRWMutex) lockBlocking(timeout time.Duration, id, source string, isReadLock bool) (locked bool) {
	doneCh, start := make(chan struct{}), time.Now().UTC()
	defer close(doneCh)

	// Use incremental back-off algorithm for repeated attempts to acquire the lock
	for range newRetryTimerSimple(doneCh) {
		// Create temp array on stack.
		locks := make([]string, dm.clnt.dNodeCount)

		// Try to acquire the lock.
		success := lock(dm.clnt, &locks, dm.Name, id, source, isReadLock)
		if success {
			dm.m.Lock()
			defer dm.m.Unlock()

			// If success, copy array to object
			if isReadLock {
				// Append new array of strings at the end
				dm.readersLocks = append(dm.readersLocks, make([]string, dm.clnt.dNodeCount))
				// and copy stack array into last spot
				copy(dm.readersLocks[len(dm.readersLocks)-1], locks[:])
			} else {
				copy(dm.writeLocks, locks[:])
			}

			return true
		}
		if time.Now().UTC().Sub(start) >= timeout { // Are we past the timeout?
			break
		}
		// Failed to acquire the lock on this attempt, incrementally wait
		// for a longer back-off time and try again afterwards.
	}
	return false
}
1062140
func (rw *RWMutex) Lock() {
	if rw.readLockCounter != 0 || rw.writeLocked {
		panic("nosync: mutex is already locked")
	}
	rw.writeLocked = true
}
978534
func (md *MDServerMemory) Lock(ctx context.Context,
	tlfID tlf.ID, lockID keybase1.LockID) error {
	// An RPC-based client would receive a throttle message from the
	// server and retry with backoff, but here we need to implement
	// the retry logic explicitly.
	for {
		ch := md.doLock(ctx, tlfID, lockID)
		if ch == nil {
			return nil
		}
		select {
		// TODO: wait for the clock to pass the expired time.  We'd
		// need a new method in the `Clock` interface to support this.
		case <-ch:
			continue
		case <-ctx.Done():
			return ctx.Err()
		}
	}
}
1012789
func (l *lockTracker) Lock(id string) {
	l.seenMu.RLock()
	if _, seen := l.seen[id]; !seen {
		l.seenMu.RUnlock()
		l.seenMu.Lock()
		l.seen[id] = struct{}{}
		l.seenMu.Unlock()
	} else {
		l.seenMu.RUnlock()
	}

	l.Locker.Lock(id)
}
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
}
93785
func ServiceLock(conn client.Connection) (client.Lock, error) {
	return conn.NewLock(zkServiceLock)
}
1160021
func (fs *FSObjects) GetObjectNInfo(ctx context.Context, bucket, object string, rs *HTTPRangeSpec, h http.Header, lockType LockType, opts ObjectOptions) (gr *GetObjectReader, err error) {

	if err = checkGetObjArgs(ctx, bucket, object); err != nil {
		return nil, err
	}

	if _, err = fs.statBucketDir(ctx, bucket); err != nil {
		return nil, toObjectErr(err, bucket)
	}

	var nsUnlocker = func() {}

	if lockType != noLock {
		// Lock the object before reading.
		lock := fs.nsMutex.NewNSLock(bucket, object)
		switch lockType {
		case writeLock:
			if err = lock.GetLock(globalObjectTimeout); err != nil {
				logger.LogIf(ctx, err)
				return nil, err
			}
			nsUnlocker = lock.Unlock
		case readLock:
			if err = lock.GetRLock(globalObjectTimeout); err != nil {
				logger.LogIf(ctx, err)
				return nil, err
			}
			nsUnlocker = lock.RUnlock
		}
	}

	// Otherwise we get the object info
	var objInfo ObjectInfo
	if objInfo, err = fs.getObjectInfo(ctx, bucket, object); err != nil {
		nsUnlocker()
		return nil, toObjectErr(err, bucket, object)
	}
	// For a directory, we need to send an reader that returns no bytes.
	if hasSuffix(object, slashSeparator) {
		// The lock taken above is released when
		// objReader.Close() is called by the caller.
		return NewGetObjectReaderFromReader(bytes.NewBuffer(nil), objInfo, opts.CheckCopyPrecondFn, nsUnlocker)
	}
	// Take a rwPool lock for NFS gateway type deployment
	rwPoolUnlocker := func() {}
	if bucket != minioMetaBucket && lockType != noLock {
		fsMetaPath := pathJoin(fs.fsPath, minioMetaBucket, bucketMetaPrefix, bucket, object, fs.metaJSONFile)
		_, err = fs.rwPool.Open(fsMetaPath)
		if err != nil && err != errFileNotFound {
			logger.LogIf(ctx, err)
			nsUnlocker()
			return nil, toObjectErr(err, bucket, object)
		}
		// Need to clean up lock after getObject is
		// completed.
		rwPoolUnlocker = func() { fs.rwPool.Close(fsMetaPath) }
	}

	objReaderFn, off, length, rErr := NewGetObjectReader(rs, objInfo, opts.CheckCopyPrecondFn, nsUnlocker, rwPoolUnlocker)
	if rErr != nil {
		return nil, rErr
	}

	// Read the object, doesn't exist returns an s3 compatible error.
	fsObjPath := pathJoin(fs.fsPath, bucket, object)
	readCloser, size, err := fsOpenFile(ctx, fsObjPath, off)
	if err != nil {
		rwPoolUnlocker()
		nsUnlocker()
		return nil, toObjectErr(err, bucket, object)
	}
	reader := io.LimitReader(readCloser, length)
	closeFn := func() {
		readCloser.Close()
	}

	// Check if range is valid
	if off > size || off+length > size {
		err = InvalidRange{off, length, size}
		logger.LogIf(ctx, err)
		closeFn()
		rwPoolUnlocker()
		nsUnlocker()
		return nil, err
	}

	return objReaderFn(reader, h, opts.CheckCopyPrecondFn, closeFn)
}
1315488
func (n *nsLockMap) Lock(volume, path, opsID string, timeout time.Duration) (locked bool) {
	readLock := false // This is a write lock.

	lockSource := getSource() // Useful for debugging
	return n.lock(volume, path, lockSource, opsID, readLock, timeout)
}
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
}
459535
func (f *Flock) Locked() bool {
	f.m.RLock()
	defer f.m.RUnlock()
	return f.l
}
447274
func (c Client) StatObject(bucketName, objectName string, opts StatObjectOptions) (ObjectInfo, error) {
	// Input validation.
	if err := s3utils.CheckValidBucketName(bucketName); err != nil {
		return ObjectInfo{}, err
	}
	if err := s3utils.CheckValidObjectName(objectName); err != nil {
		return ObjectInfo{}, err
	}
	return c.statObject(context.Background(), bucketName, objectName, opts)
}
677242
func (e *defaultStoreEnumerator) Lock(volumeID string) (interface{}, error) {
	return e.kvdb.Lock(e.lockKey(volumeID))
}
51603
func (client *lockRESTClient) RUnlock(args dsync.LockArgs) (reply bool, err error) {
	return client.restCall(lockRESTMethodRUnlock, args)
}