cutil: fix race condition in ptrguard tests

The finalizer of an object is called in a separate go routine, so we
might have to check several times for its completion.

Fixes: #545

Signed-off-by: Sven Anderson <sven@redhat.com>
This commit is contained in:
Sven Anderson 2021-08-10 18:27:37 +02:00 committed by John Mulligan
parent d7716cc989
commit 46300ecae8
1 changed files with 9 additions and 6 deletions

View File

@ -4,6 +4,7 @@ import (
"math/rand" "math/rand"
"runtime" "runtime"
"testing" "testing"
"time"
"unsafe" "unsafe"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -42,7 +43,7 @@ func TestPtrGuard(t *testing.T) {
// until the function returns after Release() is called. The test will // until the function returns after Release() is called. The test will
// fail if the //go:uintptrescapes comment is disabled (removed) or // fail if the //go:uintptrescapes comment is disabled (removed) or
// stops working in future versions of go. // stops working in future versions of go.
var pg_done, u_done bool var pgDone, uDone bool
var goPtr = func(b *bool) unsafe.Pointer { var goPtr = func(b *bool) unsafe.Pointer {
s := "ok" s := "ok"
runtime.SetFinalizer(&s, func(p *string) { *b = true }) runtime.SetFinalizer(&s, func(p *string) { *b = true })
@ -50,14 +51,16 @@ func TestPtrGuard(t *testing.T) {
} }
cPtr := Malloc(PtrSize) cPtr := Malloc(PtrSize)
defer Free(cPtr) defer Free(cPtr)
pg := NewPtrGuard(cPtr, goPtr(&pg_done)) pg := NewPtrGuard(cPtr, goPtr(&pgDone))
u := uintptr(goPtr(&u_done)) u := uintptr(goPtr(&uDone))
runtime.GC() runtime.GC()
assert.True(t, u_done) assert.Eventually(t, func() bool { return uDone },
assert.False(t, pg_done) time.Second, 10*time.Millisecond)
assert.False(t, pgDone)
pg.Release() pg.Release()
runtime.GC() runtime.GC()
assert.True(t, pg_done) assert.Eventually(t, func() bool { return pgDone },
time.Second, 10*time.Millisecond)
assert.NotZero(t, u) // avoid "unused" error assert.NotZero(t, u) // avoid "unused" error
}) })