// lockPortable is a portable version not using fcntl. Doesn't handle crashes as gracefully,
// since it can leave stale lock files.
504273
func lockPortable(name string) (io.Closer, error) {
	fi, err := os.Stat(name)
	if err == nil && fi.Size() > 0 {
		st := portableLockStatus(name)
		switch st {
		case statusLocked:
			return nil, fmt.Errorf("file %q already locked", name)
		case statusStale:
			os.Remove(name)
		case statusInvalid:
			return nil, fmt.Errorf("can't Lock file %q: has invalid contents", name)
		}
	}
	f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_EXCL, 0666)
	if err != nil {
		return nil, fmt.Errorf("failed to create lock file %s %v", name, err)
	}
	if err := json.NewEncoder(f).Encode(&pidLockMeta{OwnerPID: os.Getpid()}); err != nil {
		return nil, fmt.Errorf("cannot write owner pid: %v", err)
	}
	return &unlocker{
		f:        f,
		abs:      name,
		portable: true,
	}, nil
}
571536
func (t *TxSerializer) lockLocked(ctx context.Context, key, table string) (bool, error) {
	q, ok := t.queues[key]
	if !ok {
		// First transaction in the queue i.e. we don't wait and return immediately.
		t.queues[key] = newQueueForFirstTransaction(t.concurrentTransactions)
		t.globalSize++
		return false, nil
	}

	if t.globalSize >= t.maxGlobalQueueSize {
		if t.dryRun {
			globalQueueExceededDryRun.Add(1)
			t.logGlobalQueueExceededDryRun.Warningf("Would have rejected BeginExecute RPC because there are too many queued transactions (%d >= %d)", t.globalSize, t.maxGlobalQueueSize)
		} else {
			globalQueueExceeded.Add(1)
			return false, vterrors.Errorf(vtrpcpb.Code_RESOURCE_EXHAUSTED,
				"hot row protection: too many queued transactions (%d >= %d)", t.globalSize, t.maxGlobalQueueSize)
		}
	}

	if q.size >= t.maxQueueSize {
		if t.dryRun {
			queueExceededDryRun.Add(table, 1)
			t.logQueueExceededDryRun.Warningf("Would have rejected BeginExecute RPC because there are too many queued transactions (%d >= %d) for the same row (table + WHERE clause: '%v')", q.size, t.maxQueueSize, key)
		} else {
			queueExceeded.Add(table, 1)
			return false, vterrors.Errorf(vtrpcpb.Code_RESOURCE_EXHAUSTED,
				"hot row protection: too many queued transactions (%d >= %d) for the same row (table + WHERE clause: '%v')", q.size, t.maxQueueSize, key)
		}
	}

	if q.availableSlots == nil {
		// Hot row detected: A second, concurrent transaction is seen for the
		// first time.

		// As an optimization, we deferred the creation of the channel until now.
		q.availableSlots = make(chan struct{}, t.concurrentTransactions)
		q.availableSlots <- struct{}{}

		// Include first transaction in the count at /debug/hotrows. (It was not
		// recorded on purpose because it did not wait.)
		t.Record(key)
	}

	t.globalSize++
	q.size++
	q.count++
	if q.size > q.max {
		q.max = q.size
	}
	// Publish the number of waits at /debug/hotrows.
	t.Record(key)

	if t.dryRun {
		waitsDryRun.Add(table, 1)
		t.logWaitsDryRun.Warningf("Would have queued BeginExecute RPC for row (range): '%v' because another transaction to the same range is already in progress.", key)
		return false, nil
	}

	// Unlock before the wait and relock before returning because our caller
	// Wait() holds the lock and assumes it still has it.
	t.mu.Unlock()
	defer t.mu.Lock()

	// Non-blocking write attempt to get a slot.
	select {
	case q.availableSlots <- struct{}{}:
		// Return waited=false because a slot was immediately available.
		return false, nil
	default:
	}

	// Blocking wait for the next available slot.
	waits.Add(table, 1)
	select {
	case q.availableSlots <- struct{}{}:
		return true, nil
	case <-ctx.Done():
		return true, ctx.Err()
	}
}
1239551
func (client *lockRESTClient) Unlock(args dsync.LockArgs) (reply bool, err error) {
	return client.restCall(lockRESTMethodUnlock, args)
}
1330069
func funlock(file *os.File) error {
	return syscall.Flock(int(file.Fd()), syscall.LOCK_UN)
}
349168
func (f *LockPIDFile) Lock() (err error) {
	// make the parent directory
	_, err = os.Stat(filepath.Dir(f.name))
	if os.IsNotExist(err) {
		err = os.MkdirAll(filepath.Dir(f.name), 0700)
		if err != nil {
			return err
		}
	} else if err != nil {
		return err
	}

	if f.file, err = os.OpenFile(f.name, os.O_CREATE|os.O_RDWR, 0600); err != nil {
		return err
	}

	// LOCK_EX = exclusive
	// LOCK_NB = nonblocking
	if err = syscall.Flock(int(f.file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
		f.file.Close()
		f.file = nil
		return err
	}

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

	f.log.Debugf("Locked pidfile %s for pid=%d", f.name, pid)

	return nil
}
98497
func (l *Lock) Unlock() error {
	if l == nil {
		return nil
	}

	// Unlock kvstore mutex first
	err := l.kvLock.Unlock()

	// unlock local lock even if kvstore cannot be unlocked
	kvstoreLocks.unlock(l.path, l.id)
	Trace("Unlocked", nil, logrus.Fields{fieldKey: l.path})

	return err
}
857576
func LockedOpenFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
	return lockedOpenFile(path, flag, perm, syscall.F_SETLKW)
}
1078024
func (p *PoolConn) MarkUnusable() {
	p.mu.Lock()
	p.unusable = true
	p.mu.Unlock()
}
351969
func (ss *FileSubStore) lockFile() error {
	wasOpened, err := ss.fm.lockFile(ss.file)
	if err != nil {
		return err
	}
	// If file was not opened, we need to reset ss.writer
	if !wasOpened {
		if ss.bw != nil {
			ss.writer = ss.bw.createNewWriter(ss.file.handle)
		} else {
			ss.writer = ss.file.handle
		}
	}
	return nil
}
347097
func LockFile(filelockpath string) (*os.File, error) {

	if true {
		// take advantage of Open and O_EXCL (man creat for more info)
		// the downside of this approach is that killing the application
		// will prevent file lockfile cleanup even if there is a defer os.Remove(lockfile)
	WAIT_FOR_LOCK:
		for {
			glog.V(2).Infof("locking file: %s", filelockpath)
			fp, err := os.OpenFile(filelockpath, syscall.O_RDWR|syscall.O_CREAT|syscall.O_EXCL, 0600)
			if err != nil {
				if !strings.Contains(err.Error(), syscall.EEXIST.Error()) {
					return nil, err
				}
			} else {
				glog.V(2).Infof("locked file: %s", filelockpath)
				return fp, nil
			}

			glog.Infof("waiting to lock file: %s", filelockpath)
			select {
			case <-time.After(1 * time.Second):
				continue WAIT_FOR_LOCK
			}
		}

		//return nil, fmt.Errorf("timed out waiting to lock file %s", filelockpath)
	} else {

		// other failed attempts to lock file using fcntl/flock/...
		fp, err := os.OpenFile(filelockpath, syscall.O_RDWR|syscall.O_CREAT, 0600)
		if err != nil {
			return nil, err
		}

		glog.V(2).Infof("locking file: %s", filelockpath)
		if false {
			// FIXME: this is not working from GO, but works from C - thread issue even when sync mutex is used
			var flp = C.CString(filelockpath)
			defer C.free(unsafe.Pointer(flp))
			rc := C.fd_lock(C.int(fp.Fd()), flp)
			if 0 != rc {
				return nil, fmt.Errorf("unable to lock file %s", filelockpath)
			}
			/*
				} else if false {
					// BEWARE: flock does not work when two hosts are NFS locking
					// flock tested and works on ubuntu: ext4, btrfs, NFS (same host)
					// flock tested on centos: tmpfs, ext4, btrfs, NFS (same host)
					if err := unix.Flock(int(fp.Fd()), unix.LOCK_EX); err != nil {
						return nil, err
					}
				} else if false {
					// FIXME: unix.FcntlFlock is not working - thread issue and NFS issue
					ft := unix.Flock_t{
						Type:   syscall.F_WRLCK,         //Type of lock: F_RDLCK, F_WRLCK, F_UNLCK
						Whence: int16(os.SEEK_SET),      // How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END
						Start:  0,                       // Starting offset for lock
						Len:    0,                       // Number of bytes to lock
						Pid:    int32(syscall.Getpid()), // PID of process blocking our lock (F_GETLK only)
					}
					glog.V(2).Infof("syscall.Flock_t %#v", ft)

					if err := unix.FcntlFlock(fp.Fd(), syscall.F_SETLKW, &ft); err != nil {
						return nil, err
					}
			*/
		} else if false {
			// FIXME: flock does not work when two hosts are NFS locking
			// flock tested and works on ubuntu: ext4, btrfs, NFS (same host)
			// flock tested on centos: tmpfs, ext4, btrfs, NFS (same host)
			if err := syscall.Flock(int(fp.Fd()), syscall.LOCK_EX); err != nil {
				return nil, err
			}
		} else if false {
			// FIXME: syscall.FcntlFlock is not working - thread issue and syscall issue and NFS issue
			ft := syscall.Flock_t{
				Type:   syscall.F_WRLCK,         //Type of lock: F_RDLCK, F_WRLCK, F_UNLCK
				Whence: int16(os.SEEK_SET),      // How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END
				Start:  0,                       // Starting offset for lock
				Len:    0,                       // Number of bytes to lock
				Pid:    int32(syscall.Getpid()), // PID of process blocking our lock (F_GETLK only)
			}
			glog.V(2).Infof("syscall.Flock_t %#v", ft)

			if err := syscall.FcntlFlock(fp.Fd(), syscall.F_SETLKW /* F_GETLK, F_SETLK, F_SETLKW */, &ft); err != nil {
				return nil, err
			}
		} else if false {
			// FIXME: syscall.FcntlFlock is not working - thread issue and syscall issue and NFS issue
			// This type matches C's "struct flock" defined in /usr/include/x86_64-linux-gnu/bits/fcntl.h
			k := struct {
				Type   uint32
				Whence uint32
				Start  uint64
				Len    uint64
				Pid    uint32
			}{
				Type:   syscall.F_WRLCK,
				Whence: uint32(os.SEEK_SET),
				Start:  0,
				Len:    0, // 0 means to lock the entire file.
				Pid:    uint32(os.Getpid()),
			}

			glog.V(2).Infof("mimic /usr/include/x86_64-linux-gnu/bits/fcntl.h syscall.Flock_t %#v", k)
			_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, fp.Fd(), uintptr(syscall.F_SETLK), uintptr(unsafe.Pointer(&k)))
			if errno != 0 {
				fp.Close()
				return nil, fmt.Errorf("syscall.Syscall error: %s", errno)
			}
		} else {
			return nil, fmt.Errorf("all filelocking implementations fail")
		}

		glog.V(2).Infof("locked  file: %s", filelockpath)
		return fp, nil
	}
}
841342
func lockedOpenFile(path string, flag int, perm os.FileMode, lockType int) (*LockedFile, error) {
	switch flag {
	case syscall.O_RDONLY:
		lockType |= syscall.LOCK_SH
	case syscall.O_WRONLY:
		fallthrough
	case syscall.O_RDWR:
		fallthrough
	case syscall.O_WRONLY | syscall.O_CREAT:
		fallthrough
	case syscall.O_RDWR | syscall.O_CREAT:
		lockType |= syscall.LOCK_EX
	default:
		return nil, fmt.Errorf("Unsupported flag (%d)", flag)
	}

	f, err := os.OpenFile(path, flag|syscall.O_SYNC, perm)
	if err != nil {
		return nil, err
	}

	if err = syscall.Flock(int(f.Fd()), lockType); err != nil {
		f.Close()
		if err == syscall.EWOULDBLOCK {
			err = ErrAlreadyLocked
		}
		return nil, err
	}

	st, err := os.Stat(path)
	if err != nil {
		f.Close()
		return nil, err
	}

	if st.IsDir() {
		f.Close()
		return nil, &os.PathError{
			Op:   "open",
			Path: path,
			Err:  syscall.EISDIR,
		}
	}

	return &LockedFile{File: f}, nil
}
915608
func unlock() error {
	lock, err := getLockfile()
	if err != nil {
		return fmt.Errorf("[unlock] cannot init lockfile: %v", err)
	}
	err = lock.Unlock()
	if err != nil {
		return fmt.Errorf("[unlock] error releasing lock: %s", err)
	}
	logrus.Debugf("[unlock] lock released")
	daemonMutex.Unlock()
	return nil
}
451798
func (l *lockfile) lock(l_type int16) {
	lk := unix.Flock_t{
		Type:   l_type,
		Whence: int16(os.SEEK_SET),
		Start:  0,
		Len:    0,
	}
	switch l_type {
	case unix.F_RDLCK:
		l.rwMutex.RLock()
	case unix.F_WRLCK:
		l.rwMutex.Lock()
	default:
		panic(fmt.Sprintf("attempted to acquire a file lock of unrecognized type %d", l_type))
	}
	l.stateMutex.Lock()
	defer l.stateMutex.Unlock()
	if l.counter == 0 {
		// If we're the first reference on the lock, we need to open the file again.
		fd, err := openLock(l.file, l.ro)
		if err != nil {
			panic(fmt.Sprintf("error opening %q", l.file))
		}
		unix.CloseOnExec(fd)
		l.fd = uintptr(fd)

		// Optimization: only use the (expensive) fcntl syscall when
		// the counter is 0.  In this case, we're either the first
		// reader lock or a writer lock.
		for unix.FcntlFlock(l.fd, unix.F_SETLKW, &lk) != nil {
			time.Sleep(10 * time.Millisecond)
		}
	}
	l.locktype = l_type
	l.locked = true
	l.counter++
}
617471
func (s *PortManager) ReleasePort(networks []tcpip.NetworkProtocolNumber, transport tcpip.TransportProtocolNumber, addr tcpip.Address, port uint16) {
	s.mu.Lock()
	defer s.mu.Unlock()

	for _, network := range networks {
		desc := portDescriptor{network, transport, port}
		if m, ok := s.allocatedPorts[desc]; ok {
			n, ok := m[addr]
			if !ok {
				continue
			}
			n.refs--
			if n.refs == 0 {
				delete(m, addr)
			} else {
				m[addr] = n
			}
			if len(m) == 0 {
				delete(s.allocatedPorts, desc)
			}
		}
	}
}
103530
func (c *Config) allowPort(port int) bool {
	for _, p := range c.Outgoing.DenyPorts {
		if p == port {
			return false
		}
	}
	return true
}
554352
func RLockedOpenFile(path string) (*RLockedFile, error) {
	lkFile, err := LockedOpenFile(path, os.O_RDONLY, 0666)
	if err != nil {
		return nil, err
	}

	return newRLockedFile(lkFile)

}
984897
func (a *API) renameExportable() {
	for name, op := range a.Operations {
		newName := a.ExportableName(name)
		if newName != name {
			delete(a.Operations, name)
			a.Operations[newName] = op
		}
		op.ExportedName = newName
	}

	for k, s := range a.Shapes {
		// FIXME SNS has lower and uppercased shape names with the same name,
		// except the lowercased variant is used exclusively for string and
		// other primitive types. Renaming both would cause a collision.
		// We work around this by only renaming the structure shapes.
		if s.Type == "string" {
			continue
		}

		for mName, member := range s.MemberRefs {
			ref := s.MemberRefs[mName]
			ref.OrigShapeName = mName
			s.MemberRefs[mName] = ref

			newName := a.ExportableName(mName)
			if newName != mName {
				delete(s.MemberRefs, mName)
				s.MemberRefs[newName] = member

				// also apply locationName trait so we keep the old one
				// but only if there's no locationName trait on ref or shape
				if member.LocationName == "" && member.Shape.LocationName == "" {
					member.LocationName = mName
				}
			}

			if newName == "_" {
				panic("Shape " + s.ShapeName + " uses reserved member name '_'")
			}
		}

		newName := a.ExportableName(k)
		if newName != s.ShapeName {
			s.Rename(newName)
		}

		s.Payload = a.ExportableName(s.Payload)

		// fix required trait names
		for i, n := range s.Required {
			s.Required[i] = a.ExportableName(n)
		}
	}

	for _, s := range a.Shapes {
		// fix enum names
		if s.IsEnum() {
			s.EnumConsts = make([]string, len(s.Enum))
			for i := range s.Enum {
				shape := s.ShapeName
				shape = strings.ToUpper(shape[0:1]) + shape[1:]
				s.EnumConsts[i] = shape + s.EnumName(i)
			}
		}
	}
}