2019-01-07 19:00:40 +00:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information
|
|
|
|
|
|
|
|
package sync2_test
|
|
|
|
|
|
|
|
import (
|
2019-10-28 14:04:31 +00:00
|
|
|
"context"
|
2019-01-07 19:00:40 +00:00
|
|
|
"errors"
|
|
|
|
"sync/atomic"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"golang.org/x/sync/errgroup"
|
|
|
|
|
|
|
|
"storj.io/storj/internal/sync2"
|
2019-10-28 14:04:31 +00:00
|
|
|
"storj.io/storj/internal/testcontext"
|
2019-01-07 19:00:40 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestFence(t *testing.T) {
|
2019-02-20 09:22:53 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2019-10-28 14:04:31 +00:00
|
|
|
ctx := testcontext.NewWithTimeout(t, 30*time.Second)
|
|
|
|
defer ctx.Cleanup()
|
|
|
|
|
2019-01-07 19:00:40 +00:00
|
|
|
var group errgroup.Group
|
|
|
|
var fence sync2.Fence
|
|
|
|
var done int32
|
|
|
|
|
|
|
|
for i := 0; i < 10; i++ {
|
|
|
|
group.Go(func() error {
|
2019-10-28 14:04:31 +00:00
|
|
|
if !fence.Wait(ctx) {
|
|
|
|
return errors.New("got false from Wait")
|
|
|
|
}
|
2019-01-07 19:00:40 +00:00
|
|
|
if atomic.LoadInt32(&done) == 0 {
|
|
|
|
return errors.New("fence not yet released")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// wait a bit for all goroutines to hit the fence
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
|
|
|
|
for i := 0; i < 3; i++ {
|
|
|
|
group.Go(func() error {
|
|
|
|
atomic.StoreInt32(&done, 1)
|
|
|
|
fence.Release()
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := group.Wait(); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
2019-10-28 14:04:31 +00:00
|
|
|
|
|
|
|
func TestFence_ContextCancel(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
tctx := testcontext.NewWithTimeout(t, 30*time.Second)
|
|
|
|
defer tctx.Cleanup()
|
|
|
|
|
|
|
|
ctx, cancel := context.WithCancel(tctx)
|
|
|
|
|
|
|
|
var group errgroup.Group
|
|
|
|
var fence sync2.Fence
|
|
|
|
|
|
|
|
for i := 0; i < 10; i++ {
|
|
|
|
group.Go(func() error {
|
|
|
|
if fence.Wait(ctx) {
|
|
|
|
return errors.New("got true from Wait")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// wait a bit for all goroutines to hit the fence
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
|
|
|
|
cancel()
|
|
|
|
|
|
|
|
if err := group.Wait(); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|