| |
| |
| |
|
|
| |
| |
|
|
| package main |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| import "C" |
|
|
| import ( |
| "fmt" |
| "runtime" |
| "strings" |
| ) |
|
|
| var baseGoroutines int |
|
|
| func init() { |
| register("NumGoroutine", NumGoroutine) |
| } |
|
|
| func NumGoroutine() { |
| |
| |
| |
| if _, ok := checkNumGoroutine("first", 1+baseGoroutines); !ok { |
| return |
| } |
|
|
| |
| if C.CheckNumGoroutine(); !callbackok { |
| return |
| } |
|
|
| |
| if _, ok := checkNumGoroutine("third", 1+baseGoroutines); !ok { |
| return |
| } |
|
|
| fmt.Println("OK") |
| } |
|
|
| func checkNumGoroutine(label string, want int) (string, bool) { |
| n := runtime.NumGoroutine() |
| if n != want { |
| fmt.Printf("%s NumGoroutine: want %d; got %d\n", label, want, n) |
| return "", false |
| } |
|
|
| sbuf := make([]byte, 32<<10) |
| sbuf = sbuf[:runtime.Stack(sbuf, true)] |
| n = strings.Count(string(sbuf), "goroutine ") |
| if n != want { |
| fmt.Printf("%s Stack: want %d; got %d:\n%s\n", label, want, n, sbuf) |
| return "", false |
| } |
| return string(sbuf), true |
| } |
|
|
| var callbackok bool |
|
|
| |
| func CallbackNumGoroutine() { |
| stk, ok := checkNumGoroutine("second", 2+baseGoroutines) |
| if !ok { |
| return |
| } |
| if !strings.Contains(stk, "CallbackNumGoroutine") { |
| fmt.Printf("missing CallbackNumGoroutine from stack:\n%s\n", stk) |
| return |
| } |
|
|
| callbackok = true |
| } |
|
|