github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/runtime/internal/luagc/weakref.go (about)

     1  // Package luagc implements weak refs and weak ref pools to be used by the
     2  // Golua runtime.
     3  //
     4  // Two interfaces WeakRef and Pool are defined and the packages provides three
     5  // implementations of Pool.  The Golua runtime has a Pool instance that
     6  // it uses to help with finalizing of Lua values and making sure finalizers do
     7  // not run after the runtime has finished.
     8  //
     9  // SafePool is a simple implementation whose strategy is to keep all
    10  // values alive as long as they have live WeakRefs.
    11  //
    12  // UnsafePool makes every effort to let values be GCed when they are only
    13  // reachable via WeakRefs.  It relies on casting interface{} to unsafe pointers
    14  // and back again, which would break if Go were to have a moving GC.
    15  //
    16  // ClonePool also lets values be GCed when they are unreachable outside of the
    17  // pool and does so on any compliant Go implementation.  However it does not
    18  // support WeakRefs (i.e. Get(v) always returns nil).
    19  package luagc
    20  
    21  // Value is the interface that must be implemented by values managed by a Pool.
    22  type Value interface {
    23  
    24  	// Key returns a Key instance that is unique to a Value and its clones (i.e.
    25  	// v.Key() == v.Clone().Key(), but two independent values should have
    26  	// distinct keys)
    27  	Key() Key
    28  
    29  	// Clone() returns a copy of the value that behaves like the original value
    30  	// (in particular it shares its state).
    31  	Clone() Value
    32  }
    33  
    34  // Key is the type for value keys (see the Value interface).
    35  type Key interface{}
    36  
    37  // A WeakRef is a weak reference to a value. Its Value() method returns the
    38  // value if it is not dead (meaning that the value is still reachable),
    39  // otherwise it returns nil.
    40  //
    41  // Note that it is valid for a WeakRef to keep its value alive while it is
    42  // alive, although not very efficient.
    43  type WeakRef interface {
    44  	Value() Value
    45  }
    46  
    47  // A Pool maintains a set of weak references to values.  Its methods are not
    48  // required to be thread-safe insofar as they should not get called
    49  // concurrently.
    50  //
    51  // Each Golua Runtime has a Pool instance to help it manage weak references and
    52  // finalizers.
    53  type Pool interface {
    54  
    55  	// Get returns a WeakRef for the given value v.  Calling Get several times
    56  	// with the same value should return the same WeakRef.
    57  	//
    58  	// An implementation of Pool may return nil if it is unable to make a
    59  	// WeakRef for the passed-in value.
    60  	Get(v Value) WeakRef
    61  
    62  	// Mark indicates that the pool should keep a copy of v when it becomes
    63  	// unreachable.  It can then notify the Golua runtime via the
    64  	// ExtractPendingFinalize() and ExtractPendingRelease() methods (depending
    65  	// on the flags passed in).
    66  	//
    67  	// The associated Golua Runtime marks all values which have a __gc
    68  	// metamethod with the Finalize flag, and all values which implement the
    69  	// ResourceReleaser interface with the Release flag (this is contextual
    70  	// info, this package is unaware of this).
    71  	//
    72  	// Note: "Mark" is the terminology used in the Lua docs, it is unrelated to
    73  	// "Mark and Sweep".
    74  	Mark(v Value, flags MarkFlags)
    75  
    76  	// ExtractPendingFinalize returns all marked values which are no longer reachable
    77  	// and haven't been returned yet, so that some finalizing code can be run
    78  	// with them.  The returned values are ordered in reverse order of marking
    79  	// (i.e. if v1 was marked before v2, then v2 comes before v1 in the returned
    80  	// list). Further calls should not return the same values again.
    81  	//
    82  	// This is called periodically by the Golua Runtime to run Lua finalizers on
    83  	// GCed values.
    84  	ExtractPendingFinalize() []Value
    85  
    86  	// ExtractPendingRelease returns all marked values which are no longer
    87  	// reachable, no longer need to be finalized and haven't been returned yet,
    88  	// so that their associated resources can be released.  The returned values
    89  	// are ordered in reverse order of marking (i.e. if v1 was marked before v2,
    90  	// then v2 comes before v1 in the returned list). Further calls should not
    91  	// return the same values again.
    92  	//
    93  	// This is called periodically by the Golua Runtime to release resources
    94  	// associated with GCed values.
    95  	ExtractPendingRelease() []Value
    96  
    97  	// ExtractAllMarkedFinalize returns all values marked for Lua finalizing,
    98  	// following the same order as ExtractPendingFinalize.  All marked values
    99  	// are cleared in the pool so that they will no longer be returned by this
   100  	// method or ExtractPendingFinalize.
   101  	//
   102  	// Typically this method will be called when the associated Golua Runtime is
   103  	// being closed so that all outstanding Lua finalizers can be called (even
   104  	// if their values might get GCed later).
   105  	ExtractAllMarkedFinalize() []Value
   106  
   107  	// ExtractAllMarkedRelease returns all values marked for releasing,
   108  	// following the same order as ExtractPendingRelease.  All values marked for
   109  	// Finalize or Release are cleared in the pool so that they will no longer
   110  	// be returned by any Extract* method.  This means this method should be
   111  	// called as the last action before discarding the pool.
   112  	//
   113  	// Typically this method will be called when the associated Golua Runtime is
   114  	// being closed so that all outstanding Lua finalizers can be called (even
   115  	// if their values might get GCed later).
   116  	ExtractAllMarkedRelease() []Value
   117  }
   118  
   119  // MarkFlags are passsed to the Pool.Mark method to signal to the pool how to
   120  // deal with the value when it becomes unreachable.
   121  type MarkFlags uint8
   122  
   123  const (
   124  	Finalize MarkFlags = 1 << iota // Mark a value for finalizing
   125  	Release                        // Mark a value for releasing
   126  )