github.com/comwrg/go/src@v0.0.0-20220319063731-c238d0440370/runtime/semasleep_test.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build !plan9 && !windows && !js 6 // +build !plan9,!windows,!js 7 8 package runtime_test 9 10 import ( 11 "os/exec" 12 "syscall" 13 "testing" 14 "time" 15 ) 16 17 // Issue #27250. Spurious wakeups to pthread_cond_timedwait_relative_np 18 // shouldn't cause semasleep to retry with the same timeout which would 19 // cause indefinite spinning. 20 func TestSpuriousWakeupsNeverHangSemasleep(t *testing.T) { 21 if *flagQuick { 22 t.Skip("-quick") 23 } 24 25 exe, err := buildTestProg(t, "testprog") 26 if err != nil { 27 t.Fatal(err) 28 } 29 30 start := time.Now() 31 cmd := exec.Command(exe, "After1") 32 if err := cmd.Start(); err != nil { 33 t.Fatalf("Failed to start command: %v", err) 34 } 35 doneCh := make(chan error, 1) 36 go func() { 37 doneCh <- cmd.Wait() 38 }() 39 40 // With the repro running, we can continuously send to it 41 // a non-terminal signal such as SIGIO, to spuriously 42 // wakeup pthread_cond_timedwait_relative_np. 43 unfixedTimer := time.NewTimer(2 * time.Second) 44 for { 45 select { 46 case <-time.After(200 * time.Millisecond): 47 // Send the pesky signal that toggles spinning 48 // indefinitely if #27520 is not fixed. 49 cmd.Process.Signal(syscall.SIGIO) 50 51 case <-unfixedTimer.C: 52 t.Error("Program failed to return on time and has to be killed, issue #27520 still exists") 53 cmd.Process.Signal(syscall.SIGKILL) 54 return 55 56 case err := <-doneCh: 57 if err != nil { 58 t.Fatalf("The program returned but unfortunately with an error: %v", err) 59 } 60 if time.Since(start) < 100*time.Millisecond { 61 t.Fatalf("The program stopped too quickly.") 62 } 63 return 64 } 65 } 66 }