lock

package
v0.0.0-...-4bf4b70 Latest Latest
Warning

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

Go to latest
Published: Jan 24, 2021 License: Apache-2.0, MIT Imports: 9 Imported by: 0

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 (
	// minDegree is the minimum degree of an internal node in a Set B-tree.
	//
	// - Any non-root node has at least minDegree-1 segments.
	//
	// - Any non-root internal (non-leaf) node has at least minDegree children.
	//
	// - The root node may have fewer than minDegree-1 segments, but it may
	// only have 0 segments if the tree is empty.
	//
	// Our implementation requires minDegree >= 3. Higher values of minDegree
	// usually improve performance, but increase memory usage for small sets.
	LockminDegree = 3

	LockmaxDegree = 2 * LockminDegree
)
View Source
const (
	// EventMaskAll is the mask we will always use for locks, by using the
	// same mask all the time we can wake up everyone anytime the lock
	// changes state.
	EventMaskAll waiter.EventMask = 0xFFFF
)
View Source
const LockEOF = math.MaxUint64

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.

View Source
const LocktrackGaps = 0

trackGaps is an optional parameter.

If trackGaps is 1, the Set will track maximum gap size recursively, enabling the GapIterator.{Prev,Next}LargeEnoughGap functions. In this case, Key must be an unsigned integer.

trackGaps must be 0 or 1.

Variables

This section is empty.

Functions

func LockzeroNodeSlice

func LockzeroNodeSlice(slice []*Locknode)

func LockzeroValueSlice

func LockzeroValueSlice(slice []Lock)

Types

type Blocker

type Blocker interface {
	Block(C <-chan struct{}) error
}

Blocker is the interface used for blocking locks. Passing a nil Blocker will be treated as non-blocking.

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

func (*Lock) StateFields

func (l *Lock) StateFields() []string

func (*Lock) StateLoad

func (l *Lock) StateLoad(stateSourceObject state.Source)

func (*Lock) StateSave

func (l *Lock) StateSave(stateSinkObject state.Sink)

func (*Lock) StateTypeName

func (l *Lock) StateTypeName() string

type LockGapIterator

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

A GapIterator is conceptually one of:

- A pointer to a position between two segments, before the first segment, or after the last segment in a set, called a *gap*; or

- A terminal iterator, which is a sentinel indicating that the end of iteration has been reached.

Note that the gap between two adjacent segments exists (iterators to it are non-terminal), but has a length of zero. GapIterator.IsEmpty returns true for such gaps. An empty set contains a single gap, spanning the entire range of the set's keys.

GapIterators are copyable values and are meaningfully equality-comparable. The zero value of GapIterator is a terminal iterator.

Unless otherwise specified, any mutation of a set invalidates all existing iterators into the set.

func (LockGapIterator) End

func (gap LockGapIterator) End() uint64

End is equivalent to Range().End, but should be preferred if only the end of the range is needed.

func (LockGapIterator) IsEmpty

func (gap LockGapIterator) IsEmpty() bool

IsEmpty returns true if the iterated gap is empty (that is, the "gap" is between two adjacent segments.)

func (LockGapIterator) NextGap

func (gap LockGapIterator) NextGap() LockGapIterator

NextGap returns the iterated gap's successor. If no such gap exists, NextGap returns a terminal iterator.

func (LockGapIterator) NextLargeEnoughGap

func (gap LockGapIterator) NextLargeEnoughGap(minSize uint64) LockGapIterator

NextLargeEnoughGap returns the iterated gap's first next gap with larger length than minSize. If not found, return a terminal gap iterator (does NOT include this gap itself).

Precondition: trackGaps must be 1.

func (LockGapIterator) NextSegment

func (gap LockGapIterator) NextSegment() LockIterator

NextSegment returns the segment immediately after the iterated gap. If no such segment exists, NextSegment returns a terminal iterator.

func (LockGapIterator) Ok

func (gap LockGapIterator) Ok() bool

Ok returns true if the iterator is not terminal. All other methods are only valid for non-terminal iterators.

func (LockGapIterator) PrevGap

func (gap LockGapIterator) PrevGap() LockGapIterator

PrevGap returns the iterated gap's predecessor. If no such gap exists, PrevGap returns a terminal iterator.

func (LockGapIterator) PrevLargeEnoughGap

func (gap LockGapIterator) PrevLargeEnoughGap(minSize uint64) LockGapIterator

PrevLargeEnoughGap returns the iterated gap's first prev gap with larger or equal length than minSize. If not found, return a terminal gap iterator (does NOT include this gap itself).

Precondition: trackGaps must be 1.

func (LockGapIterator) PrevSegment

func (gap LockGapIterator) PrevSegment() LockIterator

PrevSegment returns the segment immediately before the iterated gap. If no such segment exists, PrevSegment returns a terminal iterator.

func (LockGapIterator) Range

func (gap LockGapIterator) Range() LockRange

Range returns the range spanned by the iterated gap.

func (LockGapIterator) Start

func (gap LockGapIterator) Start() uint64

Start is equivalent to Range().Start, but should be preferred if only the start of the range is needed.

type LockIterator

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

A Iterator is conceptually one of:

- A pointer to a segment in a set; or

- A terminal iterator, which is a sentinel indicating that the end of iteration has been reached.

Iterators are copyable values and are meaningfully equality-comparable. The zero value of Iterator is a terminal iterator.

Unless otherwise specified, any mutation of a set invalidates all existing iterators into the set.

func LocksegmentAfterPosition

func LocksegmentAfterPosition(n *Locknode, i int) LockIterator

segmentAfterPosition returns the successor segment of the position given by n.children[i], which may or may not contain a child. If no such segment exists, segmentAfterPosition returns a terminal iterator.

func LocksegmentBeforePosition

func LocksegmentBeforePosition(n *Locknode, i int) LockIterator

segmentBeforePosition returns the predecessor segment of the position given by n.children[i], which may or may not contain a child. If no such segment exists, segmentBeforePosition returns a terminal iterator.

func (LockIterator) End

func (seg LockIterator) End() uint64

End is equivalent to Range().End, but should be preferred if only the end of the range is needed.

func (LockIterator) NextGap

func (seg LockIterator) NextGap() LockGapIterator

NextGap returns the gap immediately after the iterated segment.

func (LockIterator) NextNonEmpty

func (seg LockIterator) NextNonEmpty() (LockIterator, LockGapIterator)

NextNonEmpty returns the iterated segment's successor if it is adjacent, or the gap after the iterated segment otherwise. If seg.End() == Functions.MaxKey(), NextNonEmpty will return two terminal iterators. Otherwise, exactly one of the iterators returned by NextNonEmpty will be non-terminal.

func (LockIterator) NextSegment

func (seg LockIterator) NextSegment() LockIterator

NextSegment returns the iterated segment's successor. If there is no succeeding segment, NextSegment returns a terminal iterator.

func (LockIterator) Ok

func (seg LockIterator) Ok() bool

Ok returns true if the iterator is not terminal. All other methods are only valid for non-terminal iterators.

func (LockIterator) PrevGap

func (seg LockIterator) PrevGap() LockGapIterator

PrevGap returns the gap immediately before the iterated segment.

func (LockIterator) PrevNonEmpty

func (seg LockIterator) PrevNonEmpty() (LockIterator, LockGapIterator)

PrevNonEmpty returns the iterated segment's predecessor if it is adjacent, or the gap before the iterated segment otherwise. If seg.Start() == Functions.MinKey(), PrevNonEmpty will return two terminal iterators. Otherwise, exactly one of the iterators returned by PrevNonEmpty will be non-terminal.

func (LockIterator) PrevSegment

func (seg LockIterator) PrevSegment() LockIterator

PrevSegment returns the iterated segment's predecessor. If there is no preceding segment, PrevSegment returns a terminal iterator.

func (LockIterator) Range

func (seg LockIterator) Range() LockRange

Range returns the iterated segment's range key.

func (LockIterator) SetEnd

func (seg LockIterator) SetEnd(end uint64)

SetEnd mutates the iterated segment's end. If the new end value would cause the iterated segment to overlap another segment, or would result in an invalid range, SetEnd panics. This operation does not invalidate any iterators.

func (LockIterator) SetEndUnchecked

func (seg LockIterator) SetEndUnchecked(end uint64)

SetEndUnchecked mutates the iterated segment's end. This operation does not invalidate any iterators.

Preconditions: The new end must be valid: * end > seg.Start(). * If seg.NextSegment().Ok(), then end <= seg.NextSegment().Start().

func (LockIterator) SetRange

func (seg LockIterator) SetRange(r LockRange)

SetRange mutates the iterated segment's range key. If the new range would cause the iterated segment to overlap another segment, or if the new range is invalid, SetRange panics. This operation does not invalidate any iterators.

func (LockIterator) SetRangeUnchecked

func (seg LockIterator) SetRangeUnchecked(r LockRange)

SetRangeUnchecked mutates the iterated segment's range key. This operation does not invalidate any iterators.

Preconditions: * r.Length() > 0. * The new range must not overlap an existing one:

  • If seg.NextSegment().Ok(), then r.end <= seg.NextSegment().Start().
  • If seg.PrevSegment().Ok(), then r.start >= seg.PrevSegment().End().

func (LockIterator) SetStart

func (seg LockIterator) SetStart(start uint64)

SetStart mutates the iterated segment's start. If the new start value would cause the iterated segment to overlap another segment, or would result in an invalid range, SetStart panics. This operation does not invalidate any iterators.

func (LockIterator) SetStartUnchecked

func (seg LockIterator) SetStartUnchecked(start uint64)

SetStartUnchecked mutates the iterated segment's start. This operation does not invalidate any iterators.

Preconditions: The new start must be valid: * start < seg.End() * If seg.PrevSegment().Ok(), then start >= seg.PrevSegment().End().

func (LockIterator) SetValue

func (seg LockIterator) SetValue(val Lock)

SetValue mutates the iterated segment's value. This operation does not invalidate any iterators.

func (LockIterator) Start

func (seg LockIterator) Start() uint64

Start is equivalent to Range().Start, but should be preferred if only the start of the range is needed.

func (LockIterator) Value

func (seg LockIterator) Value() Lock

Value returns a copy of the iterated segment's value.

func (LockIterator) ValuePtr

func (seg LockIterator) ValuePtr() *Lock

ValuePtr returns a pointer to the iterated segment's value. The pointer is invalidated if the iterator is invalidated. This operation does not invalidate any iterators.

type LockRange

type LockRange struct {
	// Start is the inclusive start of the range.
	Start uint64

	// End is the exclusive end of the range.
	End uint64
}

A Range represents a contiguous range of T.

+stateify savable

func ComputeRange

func ComputeRange(start, length, offset int64) (LockRange, error)

ComputeRange takes a positive file offset and computes the start of a LockRange using start (relative to offset) and the end of the LockRange using length. The values of start and length may be negative but the resulting LockRange must preserve that LockRange.Start < LockRange.End and LockRange.Start > 0.

func (LockRange) CanSplitAt

func (r LockRange) CanSplitAt(x uint64) bool

CanSplitAt returns true if it is legal to split a segment spanning the range r at x; that is, splitting at x would produce two ranges, both of which have non-zero length.

func (LockRange) Contains

func (r LockRange) Contains(x uint64) bool

Contains returns true if r contains x.

func (LockRange) Intersect

func (r LockRange) Intersect(r2 LockRange) LockRange

Intersect returns a range consisting of the intersection between r and r2. If r and r2 do not overlap, Intersect returns a range with unspecified bounds, but for which Length() == 0.

func (LockRange) IsSupersetOf

func (r LockRange) IsSupersetOf(r2 LockRange) bool

IsSupersetOf returns true if r is a superset of r2; that is, the range r2 is contained within r.

func (LockRange) Length

func (r LockRange) Length() uint64

Length returns the length of the range.

func (LockRange) Overlaps

func (r LockRange) Overlaps(r2 LockRange) bool

Overlaps returns true if r and r2 overlap.

func (*LockRange) StateFields

func (r *LockRange) StateFields() []string

func (*LockRange) StateLoad

func (r *LockRange) StateLoad(stateSourceObject state.Source)

func (*LockRange) StateSave

func (r *LockRange) StateSave(stateSinkObject state.Sink)

func (*LockRange) StateTypeName

func (r *LockRange) StateTypeName() string

func (LockRange) WellFormed

func (r LockRange) WellFormed() bool

WellFormed returns true if r.Start <= r.End. All other methods on a Range require that the Range is well-formed.

type LockSegmentDataSlices

type LockSegmentDataSlices struct {
	Start  []uint64
	End    []uint64
	Values []Lock
}

SegmentDataSlices represents segments from a set as slices of start, end, and values. SegmentDataSlices is primarily used as an intermediate representation for save/restore and the layout here is optimized for that.

+stateify savable

func (*LockSegmentDataSlices) StateFields

func (l *LockSegmentDataSlices) StateFields() []string

func (*LockSegmentDataSlices) StateLoad

func (l *LockSegmentDataSlices) StateLoad(stateSourceObject state.Source)

func (*LockSegmentDataSlices) StateSave

func (l *LockSegmentDataSlices) StateSave(stateSinkObject state.Sink)

func (*LockSegmentDataSlices) StateTypeName

func (l *LockSegmentDataSlices) StateTypeName() string

type LockSet

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

A Set is a mapping of segments with non-overlapping Range keys. The zero value for a Set is an empty set. Set values are not safely movable nor copyable. Set is thread-compatible.

+stateify savable

func (*LockSet) Add

func (s *LockSet) Add(r LockRange, val Lock) bool

Add inserts the given segment into the set and returns true. If the new segment can be merged with adjacent segments, Add will do so. If the new segment would overlap an existing segment, Add returns false. If Add succeeds, all existing iterators are invalidated.

func (*LockSet) AddWithoutMerging

func (s *LockSet) AddWithoutMerging(r LockRange, val Lock) bool

AddWithoutMerging inserts the given segment into the set and returns true. If it would overlap an existing segment, AddWithoutMerging does nothing and returns false. If AddWithoutMerging succeeds, all existing iterators are invalidated.

func (*LockSet) ApplyContiguous

func (s *LockSet) ApplyContiguous(r LockRange, fn func(seg LockIterator)) LockGapIterator

ApplyContiguous applies a function to a contiguous range of segments, splitting if necessary. The function is applied until the first gap is encountered, at which point the gap is returned. If the function is applied across the entire range, a terminal gap is returned. All existing iterators are invalidated.

N.B. The Iterator must not be invalidated by the function.

func (*LockSet) ExportSortedSlices

func (s *LockSet) ExportSortedSlices() *LockSegmentDataSlices

ExportSortedSlices returns a copy of all segments in the given set, in ascending key order.

func (*LockSet) Find

func (s *LockSet) Find(key uint64) (LockIterator, LockGapIterator)

Find returns the segment or gap whose range contains the given key. If a segment is found, the returned Iterator is non-terminal and the returned GapIterator is terminal. Otherwise, the returned Iterator is terminal and the returned GapIterator is non-terminal.

func (*LockSet) FindGap

func (s *LockSet) FindGap(key uint64) LockGapIterator

FindGap returns the gap containing the given key. If no such gap exists (i.e. the set contains a segment containing that key), FindGap returns a terminal iterator.

func (*LockSet) FindSegment

func (s *LockSet) FindSegment(key uint64) LockIterator

FindSegment returns the segment whose range contains the given key. If no such segment exists, FindSegment returns a terminal iterator.

func (*LockSet) FirstGap

func (s *LockSet) FirstGap() LockGapIterator

FirstGap returns the first gap in the set.

func (*LockSet) FirstSegment

func (s *LockSet) FirstSegment() LockIterator

FirstSegment returns the first segment in the set. If the set is empty, FirstSegment returns a terminal iterator.

func (*LockSet) ImportSortedSlices

func (s *LockSet) ImportSortedSlices(sds *LockSegmentDataSlices) error

ImportSortedSlices initializes the given set from the given slice.

Preconditions:

  • s must be empty.
  • sds must represent a valid set (the segments in sds must have valid lengths that do not overlap).
  • The segments in sds must be sorted in ascending key order.

func (*LockSet) Insert

func (s *LockSet) Insert(gap LockGapIterator, r LockRange, val Lock) LockIterator

Insert inserts the given segment into the given gap. If the new segment can be merged with adjacent segments, Insert will do so. Insert returns an iterator to the segment containing the inserted value (which may have been merged with other values). All existing iterators (including gap, but not including the returned iterator) are invalidated.

If the gap cannot accommodate the segment, or if r is invalid, Insert panics.

Insert is semantically equivalent to a InsertWithoutMerging followed by a Merge, but may be more efficient. Note that there is no unchecked variant of Insert since Insert must retrieve and inspect gap's predecessor and successor segments regardless.

func (*LockSet) InsertWithoutMerging

func (s *LockSet) InsertWithoutMerging(gap LockGapIterator, r LockRange, val Lock) LockIterator

InsertWithoutMerging inserts the given segment into the given gap and returns an iterator to the inserted segment. All existing iterators (including gap, but not including the returned iterator) are invalidated.

If the gap cannot accommodate the segment, or if r is invalid, InsertWithoutMerging panics.

func (*LockSet) InsertWithoutMergingUnchecked

func (s *LockSet) InsertWithoutMergingUnchecked(gap LockGapIterator, r LockRange, val Lock) LockIterator

InsertWithoutMergingUnchecked inserts the given segment into the given gap and returns an iterator to the inserted segment. All existing iterators (including gap, but not including the returned iterator) are invalidated.

Preconditions: * r.Start >= gap.Start(). * r.End <= gap.End().

func (*LockSet) IsEmpty

func (s *LockSet) IsEmpty() bool

IsEmpty returns true if the set contains no segments.

func (*LockSet) IsEmptyRange

func (s *LockSet) IsEmptyRange(r LockRange) bool

IsEmptyRange returns true iff no segments in the set overlap the given range. This is semantically equivalent to s.SpanRange(r) == 0, but may be more efficient.

func (*LockSet) Isolate

func (s *LockSet) Isolate(seg LockIterator, r LockRange) LockIterator

Isolate ensures that the given segment's range does not escape r by splitting at r.Start and r.End if necessary, and returns an updated iterator to the bounded segment. All existing iterators (including seg, but not including the returned iterators) are invalidated.

func (*LockSet) LastGap

func (s *LockSet) LastGap() LockGapIterator

LastGap returns the last gap in the set.

func (*LockSet) LastSegment

func (s *LockSet) LastSegment() LockIterator

LastSegment returns the last segment in the set. If the set is empty, LastSegment returns a terminal iterator.

func (*LockSet) LowerBoundGap

func (s *LockSet) LowerBoundGap(min uint64) LockGapIterator

LowerBoundGap returns the gap with the lowest range that is greater than or equal to min.

func (*LockSet) LowerBoundSegment

func (s *LockSet) LowerBoundSegment(min uint64) LockIterator

LowerBoundSegment returns the segment with the lowest range that contains a key greater than or equal to min. If no such segment exists, LowerBoundSegment returns a terminal iterator.

func (*LockSet) Merge

func (s *LockSet) Merge(first, second LockIterator) LockIterator

Merge attempts to merge two neighboring segments. If successful, Merge returns an iterator to the merged segment, and all existing iterators are invalidated. Otherwise, Merge returns a terminal iterator.

If first is not the predecessor of second, Merge panics.

func (*LockSet) MergeAdjacent

func (s *LockSet) MergeAdjacent(r LockRange)

MergeAdjacent attempts to merge the segment containing r.Start with its predecessor, and the segment containing r.End-1 with its successor.

func (*LockSet) MergeAll

func (s *LockSet) MergeAll()

MergeAll attempts to merge all adjacent segments in the set. All existing iterators are invalidated.

func (*LockSet) MergeRange

func (s *LockSet) MergeRange(r LockRange)

MergeRange attempts to merge all adjacent segments that contain a key in the specific range. All existing iterators are invalidated.

func (*LockSet) MergeUnchecked

func (s *LockSet) MergeUnchecked(first, second LockIterator) LockIterator

MergeUnchecked attempts to merge two neighboring segments. If successful, MergeUnchecked returns an iterator to the merged segment, and all existing iterators are invalidated. Otherwise, MergeUnchecked returns a terminal iterator.

Precondition: first is the predecessor of second: first.NextSegment() == second, first == second.PrevSegment().

func (*LockSet) Remove

func (s *LockSet) Remove(seg LockIterator) LockGapIterator

Remove removes the given segment and returns an iterator to the vacated gap. All existing iterators (including seg, but not including the returned iterator) are invalidated.

func (*LockSet) RemoveAll

func (s *LockSet) RemoveAll()

RemoveAll removes all segments from the set. All existing iterators are invalidated.

func (*LockSet) RemoveRange

func (s *LockSet) RemoveRange(r LockRange) LockGapIterator

RemoveRange removes all segments in the given range. An iterator to the newly formed gap is returned, and all existing iterators are invalidated.

func (*LockSet) Span

func (s *LockSet) Span() uint64

Span returns the total size of all segments in the set.

func (*LockSet) SpanRange

func (s *LockSet) SpanRange(r LockRange) uint64

SpanRange returns the total size of the intersection of segments in the set with the given range.

func (*LockSet) Split

func (s *LockSet) Split(seg LockIterator, split uint64) (LockIterator, LockIterator)

Split splits the given segment at the given key and returns iterators to the two resulting segments. All existing iterators (including seg, but not including the returned iterators) are invalidated.

If the segment cannot be split at split (because split is at the start or end of the segment's range, so splitting would produce a segment with zero length, or because split falls outside the segment's range altogether), Split panics.

func (*LockSet) SplitAt

func (s *LockSet) SplitAt(split uint64) bool

SplitAt splits the segment straddling split, if one exists. SplitAt returns true if a segment was split and false otherwise. If SplitAt splits a segment, all existing iterators are invalidated.

func (*LockSet) SplitUnchecked

func (s *LockSet) SplitUnchecked(seg LockIterator, split uint64) (LockIterator, LockIterator)

SplitUnchecked splits the given segment at the given key and returns iterators to the two resulting segments. All existing iterators (including seg, but not including the returned iterators) are invalidated.

Preconditions: seg.Start() < key < seg.End().

func (*LockSet) StateFields

func (s *LockSet) StateFields() []string

func (*LockSet) StateLoad

func (s *LockSet) StateLoad(stateSourceObject state.Source)

func (*LockSet) StateSave

func (s *LockSet) StateSave(stateSinkObject state.Sink)

func (*LockSet) StateTypeName

func (s *LockSet) StateTypeName() string

func (*LockSet) String

func (s *LockSet) String() string

String stringifies a Set for debugging.

func (*LockSet) UpperBoundGap

func (s *LockSet) UpperBoundGap(max uint64) LockGapIterator

UpperBoundGap returns the gap with the highest range that is less than or equal to max.

func (*LockSet) UpperBoundSegment

func (s *LockSet) UpperBoundSegment(max uint64) LockIterator

UpperBoundSegment returns the segment with the highest range that contains a key less than or equal to max. If no such segment exists, UpperBoundSegment returns a terminal iterator.

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 LockdynamicGap

type LockdynamicGap [LocktrackGaps]uint64

dynamicGap is a type that disappears if trackGaps is 0.

func (*LockdynamicGap) Get

func (d *LockdynamicGap) Get() uint64

Get returns the value of the gap.

Precondition: trackGaps must be non-zero.

func (*LockdynamicGap) Set

func (d *LockdynamicGap) Set(v uint64)

Set sets the value of the gap.

Precondition: trackGaps must be non-zero.

type Locknode

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

+stateify savable

func (*Locknode) StateFields

func (n *Locknode) StateFields() []string

func (*Locknode) StateLoad

func (n *Locknode) StateLoad(stateSourceObject state.Source)

func (*Locknode) StateSave

func (n *Locknode) StateSave(stateSinkObject state.Sink)

func (*Locknode) StateTypeName

func (n *Locknode) StateTypeName() string

func (*Locknode) String

func (n *Locknode) String() string

String stringifies a node (and all of its children) for debugging.

type Locks

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

Locks is a thread-safe wrapper around a LockSet.

+stateify savable

func (*Locks) LockRegion

func (l *Locks) LockRegion(uid UniqueID, ownerPID int32, t LockType, r LockRange, block Blocker) bool

LockRegion attempts to acquire a typed lock for the uid on a region of a file. Returns true if successful in locking the region. If false is returned, the caller should normally interpret this as "try again later" if acquiring the lock in a non-blocking mode or "interrupted" if in a blocking mode. Blocker is the interface used to provide blocking behavior, passing a nil Blocker will result in non-blocking behavior.

func (*Locks) LockRegionVFS1

func (l *Locks) LockRegionVFS1(uid UniqueID, t LockType, r LockRange, block Blocker) bool

LockRegionVFS1 is a wrapper around LockRegion for VFS1, which does not implement F_GETLK (and does not care about storing PIDs as a result).

TODO(gvisor.dev/issue/1624): Delete.

func (*Locks) StateFields

func (l *Locks) StateFields() []string

func (*Locks) StateLoad

func (l *Locks) StateLoad(stateSourceObject state.Source)

func (*Locks) StateSave

func (l *Locks) StateSave(stateSinkObject state.Sink)

func (*Locks) StateTypeName

func (l *Locks) StateTypeName() string

func (*Locks) TestRegion

func (l *Locks) TestRegion(ctx context.Context, uid UniqueID, t LockType, r LockRange) 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.

TODO(gvisor.dev/issue/5264): we don't support OFD locks through fcntl, which would return a struct with pid = -1.

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
}

OwnerInfo describes the owner of a lock.

TODO(gvisor.dev/issue/5264): We may need to add other fields in the future (e.g., Linux's file_lock.fl_flags to support open file-descriptor locks).

+stateify savable

func (*OwnerInfo) StateFields

func (o *OwnerInfo) StateFields() []string

func (*OwnerInfo) StateLoad

func (o *OwnerInfo) StateLoad(stateSourceObject state.Source)

func (*OwnerInfo) StateSave

func (o *OwnerInfo) StateSave(stateSinkObject state.Sink)

func (*OwnerInfo) StateTypeName

func (o *OwnerInfo) StateTypeName() string

type UniqueID

type UniqueID interface{}

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