mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Do not copy sleep.Waker
sleep.Waker's fields are modified as values. PiperOrigin-RevId: 320873451
This commit is contained in:
committed by
gVisor bot
parent
69f2059e5d
commit
9c32fd3f4d
@@ -12,6 +12,7 @@ go_library(
|
||||
"sleep_unsafe.go",
|
||||
],
|
||||
visibility = ["//:sandbox"],
|
||||
deps = ["//pkg/sync"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
|
||||
+7
-13
@@ -379,10 +379,7 @@ func TestRace(t *testing.T) {
|
||||
// TestRaceInOrder tests that multiple wakers can continuously send wake requests to
|
||||
// the sleeper and that the wakers are retrieved in the order asserted.
|
||||
func TestRaceInOrder(t *testing.T) {
|
||||
const wakers = 100
|
||||
const wakeRequests = 10000
|
||||
|
||||
w := make([]Waker, wakers)
|
||||
w := make([]Waker, 10000)
|
||||
s := Sleeper{}
|
||||
|
||||
// Associate each waker and start goroutines that will assert them.
|
||||
@@ -390,19 +387,16 @@ func TestRaceInOrder(t *testing.T) {
|
||||
s.AddWaker(&w[i], i)
|
||||
}
|
||||
go func() {
|
||||
n := 0
|
||||
for n < wakeRequests {
|
||||
wk := w[n%len(w)]
|
||||
wk.Assert()
|
||||
n++
|
||||
for i := range w {
|
||||
w[i].Assert()
|
||||
}
|
||||
}()
|
||||
|
||||
// Wait for all wake up notifications from all wakers.
|
||||
for i := 0; i < wakeRequests; i++ {
|
||||
v, _ := s.Fetch(true)
|
||||
if got, want := v, i%wakers; got != want {
|
||||
t.Fatalf("got %d want %d", got, want)
|
||||
for want := range w {
|
||||
got, _ := s.Fetch(true)
|
||||
if got != want {
|
||||
t.Fatalf("got %d want %d", got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,8 @@ package sleep
|
||||
import (
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -323,7 +325,12 @@ func (s *Sleeper) enqueueAssertedWaker(w *Waker) {
|
||||
//
|
||||
// This struct is thread-safe, that is, its methods can be called concurrently
|
||||
// by multiple goroutines.
|
||||
//
|
||||
// Note, it is not safe to copy a Waker as its fields are modified by value
|
||||
// (the pointer fields are individually modified with atomic operations).
|
||||
type Waker struct {
|
||||
_ sync.NoCopy
|
||||
|
||||
// s is the sleeper that this waker can wake up. Only one sleeper at a
|
||||
// time is allowed. This field can have three classes of values:
|
||||
// nil -- the waker is not asserted: it either is not associated with
|
||||
|
||||
@@ -33,6 +33,7 @@ go_library(
|
||||
"aliases.go",
|
||||
"memmove_unsafe.go",
|
||||
"mutex_unsafe.go",
|
||||
"nocopy.go",
|
||||
"norace_unsafe.go",
|
||||
"race_unsafe.go",
|
||||
"rwmutex_unsafe.go",
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright 2020 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package sync
|
||||
|
||||
// NoCopy may be embedded into structs which must not be copied
|
||||
// after the first use.
|
||||
//
|
||||
// See https://golang.org/issues/8005#issuecomment-190753527
|
||||
// for details.
|
||||
type NoCopy struct{}
|
||||
|
||||
// Lock is a no-op used by -copylocks checker from `go vet`.
|
||||
func (*NoCopy) Lock() {}
|
||||
|
||||
// Unlock is a no-op used by -copylocks checker from `go vet`.
|
||||
func (*NoCopy) Unlock() {}
|
||||
@@ -14,6 +14,7 @@
|
||||
package stack
|
||||
|
||||
import (
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
)
|
||||
@@ -24,7 +25,7 @@ import (
|
||||
// multiple endpoints. Clone() should be called in such cases so that
|
||||
// modifications to the Data field do not affect other copies.
|
||||
type PacketBuffer struct {
|
||||
_ noCopy
|
||||
_ sync.NoCopy
|
||||
|
||||
// PacketBufferEntry is used to build an intrusive list of
|
||||
// PacketBuffers.
|
||||
@@ -102,14 +103,3 @@ func (pk *PacketBuffer) Clone() *PacketBuffer {
|
||||
NatDone: pk.NatDone,
|
||||
}
|
||||
}
|
||||
|
||||
// noCopy may be embedded into structs which must not be copied
|
||||
// after the first use.
|
||||
//
|
||||
// See https://golang.org/issues/8005#issuecomment-190753527
|
||||
// for details.
|
||||
type noCopy struct{}
|
||||
|
||||
// Lock is a no-op used by -copylocks checker from `go vet`.
|
||||
func (*noCopy) Lock() {}
|
||||
func (*noCopy) Unlock() {}
|
||||
|
||||
+4
-17
@@ -15,8 +15,9 @@
|
||||
package tcpip
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
// cancellableTimerInstance is a specific instance of CancellableTimer.
|
||||
@@ -92,6 +93,8 @@ func (t *cancellableTimerInstance) stop() {
|
||||
// Note, it is not safe to copy a CancellableTimer as its timer instance creates
|
||||
// a closure over the address of the CancellableTimer.
|
||||
type CancellableTimer struct {
|
||||
_ sync.NoCopy
|
||||
|
||||
// The active instance of a cancellable timer.
|
||||
instance cancellableTimerInstance
|
||||
|
||||
@@ -157,22 +160,6 @@ func (t *CancellableTimer) Reset(d time.Duration) {
|
||||
}
|
||||
}
|
||||
|
||||
// Lock is a no-op used by the copylocks checker from go vet.
|
||||
//
|
||||
// See CancellableTimer for details about why it shouldn't be copied.
|
||||
//
|
||||
// See https://github.com/golang/go/issues/8005#issuecomment-190753527 for more
|
||||
// details about the copylocks checker.
|
||||
func (*CancellableTimer) Lock() {}
|
||||
|
||||
// Unlock is a no-op used by the copylocks checker from go vet.
|
||||
//
|
||||
// See CancellableTimer for details about why it shouldn't be copied.
|
||||
//
|
||||
// See https://github.com/golang/go/issues/8005#issuecomment-190753527 for more
|
||||
// details about the copylocks checker.
|
||||
func (*CancellableTimer) Unlock() {}
|
||||
|
||||
// NewCancellableTimer returns an unscheduled CancellableTimer with the given
|
||||
// locker and fn.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user