lock

package
v0.0.0-...-0a9b7a7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 23, 2024 License: Apache-2.0, MIT Imports: 8 Imported by: 8

Documentation

Overview

Package lock is the API for POSIX-style advisory regional file locks and BSD-style full file locks.

Callers needing to enforce these types of locks, like sys_fcntl, can call LockRegion and UnlockRegion on a thread-safe set of Locks. Locks are specific to a unique file (unique device/inode pair) and for this reason should not be shared between files.

A Lock has a set of holders identified by UniqueID. Normally this is the pid of the thread attempting to acquire the lock.

Since these are advisory locks, they do not need to be integrated into Reads/Writes and for this reason there is no way to *check* if a lock is held. One can only attempt to take a lock or unlock an existing lock.

A Lock in a set of Locks is typed: it is either a read lock with any number of readers and no writer, or a write lock with no readers.

As expected from POSIX, any attempt to acquire a write lock on a file region when there already exits a write lock held by a different uid will fail. Any attempt to acquire a write lock on a file region when there is more than one reader will fail. Any attempt to acquire a read lock on a file region when there is already a writer will fail.

In special cases, a read lock may be upgraded to a write lock and a write lock can be downgraded to a read lock. This can only happen if:

  • read lock upgrade to write lock: There can be only one reader and the reader must be the same as the requested write lock holder.

  • write lock downgrade to read lock: The writer must be the same as the requested read lock holder.

UnlockRegion always succeeds. If LockRegion fails the caller should normally interpret this as "try again later".

Index

Constants

View Source
const LockEOF = math.MaxInt64

LockEOF is the maximal possible end of a regional file lock.

A BSD-style full file lock can be represented as a regional file lock from offset 0 to LockEOF.

Variables

This section is empty.

Functions

This section is empty.

Types

type Lock

type Lock struct {
	// Readers are the set of read lock holders identified by UniqueID.
	// If len(Readers) > 0 then Writer must be nil.
	Readers map[UniqueID]OwnerInfo

	// Writer holds the writer unique ID. It's nil if there are no writers.
	Writer UniqueID

	// WriterInfo describes the writer. It is only meaningful if Writer != nil.
	WriterInfo OwnerInfo
}

Lock is a regional file lock. It consists of either a single writer or a set of readers.

A Lock may be upgraded from a read lock to a write lock only if there is a single reader and that reader has the same uid as the write lock.

A Lock may be downgraded from a write lock to a read lock only if the write lock's uid is the same as the read lock.

Accesses to Lock are synchronized through the Locks object to which it belongs.

+stateify savable

type LockType

type LockType int

LockType is a type of regional file lock.

const (
	// ReadLock describes a POSIX regional file lock to be taken
	// read only.  There may be multiple of these locks on a single
	// file region as long as there is no writer lock on the same
	// region.
	ReadLock LockType = iota

	// WriteLock describes a POSIX regional file lock to be taken
	// write only.  There may be only a single holder of this lock
	// and no read locks.
	WriteLock
)

type Locks

type Locks struct {
	// contains filtered or unexported fields
}

Locks is a thread-safe wrapper around a LockSet.

+stateify savable

func (*Locks) EventRegister

func (l *Locks) EventRegister(e *waiter.Entry) error

EventRegister implements waiter.Waitable.EventRegister.

func (*Locks) EventUnregister

func (l *Locks) EventUnregister(e *waiter.Entry)

EventUnregister implements waiter.Waitable.EventUnregister.

func (*Locks) LockRegion

func (l *Locks) LockRegion(ctx context.Context, uid UniqueID, ownerPID int32, t LockType, r LockRange, ofd bool, block bool) error

LockRegion attempts to acquire a typed lock for the uid on a region of a file. Returns nil if successful in locking the region, otherwise an appropriate error is returned.

func (*Locks) Readiness

func (l *Locks) Readiness(waiter.EventMask) waiter.EventMask

Readiness always returns zero.

func (*Locks) TestRegion

func (l *Locks) TestRegion(ctx context.Context, uid UniqueID, t LockType, r LockRange, ofd bool) linux.Flock

TestRegion checks whether the lock holder identified by uid can hold a lock of type t on range r. It returns a Flock struct representing this information as the F_GETLK fcntl does.

Note that the PID returned in the flock structure is relative to the root PID namespace. It needs to be converted to the caller's PID namespace before returning to userspace.

func (*Locks) UnlockRegion

func (l *Locks) UnlockRegion(uid UniqueID, r LockRange)

UnlockRegion attempts to release a lock for the uid on a region of a file. This operation is always successful, even if there did not exist a lock on the requested region held by uid in the first place.

type OwnerInfo

type OwnerInfo struct {
	// PID is the process ID of the lock owner.
	PID int32
	// OFD is whether this is an open file descriptor lock.
	OFD bool
}

OwnerInfo describes the owner of a lock.

+stateify savable

type UniqueID

type UniqueID any

UniqueID is a unique identifier of the holder of a regional file lock.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL