diff --git a/buffer.go b/buffer.go index 4bb5e7e..566704d 100644 --- a/buffer.go +++ b/buffer.go @@ -4,7 +4,6 @@ import ( "bytes" "io" "os" - "runtime" "unsafe" "github.com/awnumar/memguard/core" @@ -17,26 +16,16 @@ The number of LockedBuffers that you are able to create is limited by how much m */ type LockedBuffer struct { *core.Buffer - *drop } -/* -Value monitored by a finalizer so that we can clean up LockedBuffers that have gone out of scope. -*/ -type drop [16]byte - // Constructs a LockedBuffer object from a core.Buffer while also setting up the finalizer for it. func newBuffer(buf *core.Buffer) *LockedBuffer { - b := &LockedBuffer{buf, new(drop)} - runtime.SetFinalizer(b.drop, func(_ *drop) { - go buf.Destroy() - }) - return b + return &LockedBuffer{buf} } // Constructs a quasi-destroyed LockedBuffer with size zero. func newNullBuffer() *LockedBuffer { - return &LockedBuffer{new(core.Buffer), new(drop)} + return &LockedBuffer{new(core.Buffer)} } /* diff --git a/buffer_test.go b/buffer_test.go index 36c50e4..63934cd 100644 --- a/buffer_test.go +++ b/buffer_test.go @@ -12,19 +12,26 @@ import ( "unsafe" ) -func TestFinalizer(t *testing.T) { - b := NewBuffer(32) - ib := b.Buffer +func TestPtrSafetyWithGC(t *testing.T) { + dataToLock := []byte(`abcdefgh`) + b := NewBufferFromBytes(dataToLock) + dataPtr := b.Bytes() - runtime.KeepAlive(b) + finalizerCalledChan := make(chan bool) + runtime.SetFinalizer(b, func(_ *LockedBuffer) { + finalizerCalledChan <- true + }) // b is now unreachable runtime.GC() - for { - if !ib.Alive() { - break - } - runtime.Gosched() // should collect b + finalizerCalled := <-finalizerCalledChan + if finalizerCalled == false { + t.Error("this should never occur") + } + + // Check that data hasn't been garbage collected + if !bytes.Equal(dataPtr, []byte(`abcdefgh`)) { + t.Error("data does not have the value we set") } }