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 )