Commit c13bd307 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 07f26527
......@@ -25,14 +25,17 @@
package weak
import (
"fmt"
"runtime"
"sync"
"time"
"unsafe"
)
// iface is how Go runtime represents an interface.
//
// NOTE layout must be synchronized to Go runtime representation.
// NOTE depends on non-moving property of Go GC.
type iface struct {
typ uintptr // type
data uintptr // data
......@@ -77,6 +80,11 @@ func NewRef(obj interface{}) *Ref {
var release func(interface{})
release = func(obj interface{}) {
ifobj := *(*iface)(unsafe.Pointer(&obj))
if w.iface != ifobj {
panic(fmt.Sprintf("weak: release: w.iface != obj; w.iface=%x obj=%x", w.iface, ifobj))
}
// GC decided that the object is no longer reachable and
// scheduled us to run as finalizer. During the time till we
// actually run, Ref.Get might have been come to run and
......@@ -102,15 +110,21 @@ func NewRef(obj interface{}) *Ref {
// If original object is still alive - it is returned.
// If not - nil is returned.
func (w *Ref) Get() (obj interface{}) {
get := false
w.mu.Lock()
if w.state != objReleased {
w.state = objGot
get = true
}
w.mu.Unlock()
if get {
time.Sleep(100*time.Nanosecond)
// recreate interface{} from saved words.
// XXX do writes as pointers so that compiler emits write barriers to notify GC?
i := (*iface)(unsafe.Pointer(&obj))
*i = w.iface
}
w.mu.Unlock()
return obj
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment