refs

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 refs defines an interface for reference counted objects. It also provides a drop-in implementation called AtomicRefCount.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatStack

func FormatStack(pcs []uintptr) string

FormatStack converts the given stack into a readable format.

func OnExit

func OnExit()

OnExit is called on sandbox exit. It runs GC to enqueue refcount finalizers, which check for reference leaks. There is no way to guarantee that every finalizer will run before exiting, but this at least ensures that they will be discovered/enqueued by GC.

func RecordStack

func RecordStack() []uintptr

RecordStack constructs and returns the PCs on the current stack.

func SetLeakMode

func SetLeakMode(mode LeakMode)

SetLeakMode configures the reference leak checker.

Types

type AtomicRefCount

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

AtomicRefCount keeps a reference count using atomic operations and calls the destructor when the count reaches zero.

N.B. To allow the zero-object to be initialized, the count is offset by

1, that is, when refCount is n, there are really n+1 references.

+stateify savable

func (*AtomicRefCount) DecRef

func (r *AtomicRefCount) DecRef(ctx context.Context)

DecRef decrements this object's reference count.

func (*AtomicRefCount) DecRefWithDestructor

func (r *AtomicRefCount) DecRefWithDestructor(ctx context.Context, destroy func(context.Context))

DecRefWithDestructor decrements the object's reference count. If the resulting count is negative and the destructor is not nil, then the destructor will be called.

Note that speculative references are counted here. Since they were added prior to real references reaching zero, they will successfully convert to real references. In other words, we see speculative references only in the following case:

A: TryIncRef [speculative increase => sees non-negative references]
B: DecRef [real decrease]
A: TryIncRef [transform speculative to real]

func (*AtomicRefCount) EnableLeakCheck

func (r *AtomicRefCount) EnableLeakCheck(name string)

EnableLeakCheck checks for reference leaks when the AtomicRefCount gets garbage collected.

This function adds a finalizer to the AtomicRefCount, so the AtomicRefCount must be at the beginning of its parent.

name is a friendly name that will be listed as the owner of the AtomicRefCount in logs. It should be the name of the parent type, including package.

func (*AtomicRefCount) IncRef

func (r *AtomicRefCount) IncRef()

IncRef increments this object's reference count. While the count is kept greater than zero, the destructor doesn't get called.

The sanity check here is limited to real references, since if they have dropped beneath zero then the object should have been destroyed.

func (*AtomicRefCount) ReadRefs

func (r *AtomicRefCount) ReadRefs() int64

ReadRefs returns the current number of references. The returned count is inherently racy and is unsafe to use without external synchronization.

func (*AtomicRefCount) StateFields

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

func (*AtomicRefCount) StateLoad

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

func (*AtomicRefCount) StateSave

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

func (*AtomicRefCount) StateTypeName

func (r *AtomicRefCount) StateTypeName() string

func (*AtomicRefCount) TryIncRef

func (r *AtomicRefCount) TryIncRef() bool

TryIncRef attempts to increment the reference count, *unless the count has already reached zero*. If false is returned, then the object has already been destroyed, and the weak reference is no longer valid. If true if returned then a valid reference is now held on the object.

To do this safely without a loop, a speculative reference is first acquired on the object. This allows multiple concurrent TryIncRef calls to distinguish other TryIncRef calls from genuine references held.

type LeakMode

type LeakMode uint32

LeakMode configures the leak checker.

const (
	// UninitializedLeakChecking indicates that the leak checker has not yet been initialized.
	UninitializedLeakChecking LeakMode = iota

	// NoLeakChecking indicates that no effort should be made to check for
	// leaks.
	NoLeakChecking

	// LeaksLogWarning indicates that a warning should be logged when leaks
	// are found.
	LeaksLogWarning

	// LeaksLogTraces indicates that a trace collected during allocation
	// should be logged when leaks are found.
	LeaksLogTraces
)

TODO(gvisor.dev/issue/1624): Simplify down to two modes once vfs1 ref counting is gone.

func GetLeakMode

func GetLeakMode() LeakMode

GetLeakMode returns the current leak mode.

func (*LeakMode) Get

func (l *LeakMode) Get() interface{}

Get implements flag.Value.

func (*LeakMode) Set

func (l *LeakMode) Set(v string) error

Set implements flag.Value.

func (*LeakMode) String

func (l *LeakMode) String() string

String implements flag.Value.

type RefCounter

type RefCounter interface {
	// IncRef increments the reference counter on the object.
	IncRef()

	// DecRef decrements the reference counter on the object.
	//
	// Note that AtomicRefCounter.DecRef() does not support destructors.
	// If a type has a destructor, it must implement its own DecRef()
	// method and call AtomicRefCounter.DecRefWithDestructor(destructor).
	DecRef(ctx context.Context)

	// TryIncRef attempts to increase the reference counter on the object,
	// but may fail if all references have already been dropped. This
	// should be used only in special circumstances, such as WeakRefs.
	TryIncRef() bool
	// contains filtered or unexported methods
}

RefCounter is the interface to be implemented by objects that are reference counted.

type WeakRef

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

WeakRef is a weak reference.

+stateify savable

func NewWeakRef

func NewWeakRef(rc RefCounter, u WeakRefUser) *WeakRef

NewWeakRef acquires a weak reference for the given object.

An optional user will be notified when the last non-weak reference is dropped.

Note that you must hold a reference to the object prior to getting a weak reference. (But you may drop the non-weak reference after that.)

func (*WeakRef) Drop

func (w *WeakRef) Drop(ctx context.Context)

Drop drops this weak reference. You should always call drop when you are finished with the weak reference. You may not use this object after calling drop.

func (*WeakRef) Get

func (w *WeakRef) Get() RefCounter

Get attempts to get a normal reference to the underlying object, and returns the object. If this fails (the object no longer exists), then nil will be returned instead.

func (*WeakRef) Next

func (e *WeakRef) Next() *WeakRef

Next returns the entry that follows e in the list.

func (*WeakRef) Prev

func (e *WeakRef) Prev() *WeakRef

Prev returns the entry that precedes e in the list.

func (*WeakRef) SetNext

func (e *WeakRef) SetNext(elem *WeakRef)

SetNext assigns 'entry' as the entry that follows e in the list.

func (*WeakRef) SetPrev

func (e *WeakRef) SetPrev(elem *WeakRef)

SetPrev assigns 'entry' as the entry that precedes e in the list.

func (*WeakRef) StateFields

func (w *WeakRef) StateFields() []string

func (*WeakRef) StateLoad

func (w *WeakRef) StateLoad(stateSourceObject state.Source)

func (*WeakRef) StateSave

func (w *WeakRef) StateSave(stateSinkObject state.Sink)

func (*WeakRef) StateTypeName

func (w *WeakRef) StateTypeName() string

type WeakRefUser

type WeakRefUser interface {
	// WeakRefGone is called when the last non-weak reference is dropped.
	WeakRefGone(ctx context.Context)
}

A WeakRefUser is notified when the last non-weak reference is dropped.

Jump to

Keyboard shortcuts

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