You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
3.2 KiB

package main
import (
"runtime"
"sync"
"time"
)
func main() {
println("main 1")
go sub()
time.Sleep(1 * time.Millisecond)
println("main 2")
time.Sleep(2 * time.Millisecond)
println("main 3")
// Await a blocking call. This must create a new coroutine.
println("wait:")
wait()
println("end waiting")
value := delayedValue()
println("value produced after some time:", value)
// Run a non-blocking call in a goroutine. This should be turned into a
// regular call, so should be equivalent to calling nowait() without 'go'
// prefix.
go nowait()
time.Sleep(time.Millisecond)
println("done with non-blocking goroutine")
var printer Printer
printer = &myPrinter{}
printer.Print()
sleepFuncValue(func(x int) {
time.Sleep(1 * time.Millisecond)
println("slept inside func pointer", x)
})
time.Sleep(1 * time.Millisecond)
n := 20
sleepFuncValue(func(x int) {
time.Sleep(1 * time.Millisecond)
println("slept inside closure, with value:", n, x)
})
time.Sleep(2 * time.Millisecond)
var x int
go func() {
time.Sleep(2 * time.Millisecond)
x = 1
}()
time.Sleep(time.Second / 2)
println("closure go call result:", x)
time.Sleep(2 * time.Millisecond)
var m sync.Mutex
m.Lock()
println("pre-acquired mutex")
go acquire(&m)
time.Sleep(2 * time.Millisecond)
println("releasing mutex")
m.Unlock()
time.Sleep(2 * time.Millisecond)
m.Lock()
println("re-acquired mutex")
m.Unlock()
println("done")
startSimpleFunc(emptyFunc)
time.Sleep(2 * time.Millisecond)
testCond()
}
func acquire(m *sync.Mutex) {
m.Lock()
println("acquired mutex from goroutine")
time.Sleep(2 * time.Millisecond)
m.Unlock()
println("released mutex from goroutine")
}
func sub() {
println("sub 1")
time.Sleep(2 * time.Millisecond)
println("sub 2")
}
func wait() {
println(" wait start")
time.Sleep(time.Millisecond)
println(" wait end")
}
func delayedValue() int {
time.Sleep(time.Millisecond)
return 42
}
func sleepFuncValue(fn func(int)) {
go fn(8)
}
func startSimpleFunc(fn simpleFunc) {
// Test that named function types don't crash the compiler.
go fn()
}
func nowait() {
println("non-blocking goroutine")
}
type Printer interface {
Print()
}
type myPrinter struct {
}
func (i *myPrinter) Print() {
time.Sleep(time.Millisecond)
println("async interface method call")
}
type simpleFunc func()
func emptyFunc() {
}
func testCond() {
var cond runtime.Cond
go func() {
// Wait for the caller to wait on the cond.
time.Sleep(time.Millisecond)
// Notify the caller.
ok := cond.Notify()
if !ok {
panic("notification not sent")
}
// This notification will be buffered inside the cond.
ok = cond.Notify()
if !ok {
panic("notification not queued")
}
// This notification should fail, since there is already one buffered.
ok = cond.Notify()
if ok {
panic("notification double-sent")
}
}()
// Verify that the cond has no pending notifications.
ok := cond.Poll()
if ok {
panic("unexpected early notification")
}
// Wait for the goroutine spawned earlier to send a notification.
cond.Wait()
// The goroutine should have also queued a notification in the cond.
ok = cond.Poll()
if !ok {
panic("missing queued notification")
}
}