...

Source file src/runtime/semasleep_test.go

Documentation: runtime

		 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  }
		67  

View as plain text