Source file test/fixedbugs/issue52612.go

     1  // run
     2  
     3  // Copyright 2022 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  package main
     8  
     9  import (
    10  	"sync/atomic"
    11  	"unsafe"
    12  )
    13  
    14  var one interface{} = 1
    15  
    16  type eface struct {
    17  	typ  unsafe.Pointer
    18  	data unsafe.Pointer
    19  }
    20  
    21  func f(c chan struct{}) {
    22  	var x atomic.Value
    23  
    24  	go func() {
    25  		x.Swap(one) // writing using the old marker
    26  	}()
    27  	for i := 0; i < 100000; i++ {
    28  		v := x.Load() // reading using the new marker
    29  
    30  		p := (*eface)(unsafe.Pointer(&v)).typ
    31  		if uintptr(p) == ^uintptr(0) {
    32  			// We read the old marker, which the new reader
    33  			// doesn't know is a case where it should retry
    34  			// instead of returning it.
    35  			panic("bad typ field")
    36  		}
    37  	}
    38  	c <- struct{}{}
    39  }
    40  
    41  func main() {
    42  	c := make(chan struct{}, 10)
    43  	for i := 0; i < 10; i++ {
    44  		go f(c)
    45  	}
    46  	for i := 0; i < 10; i++ {
    47  		<-c
    48  	}
    49  }
    50  

View as plain text