github.com/searKing/golang/go@v1.2.117/runtime/goroutine/lock.go (about) 1 // Copyright 2020 The searKing Author. 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 // Defensive debug-only utility to track that functions run on the 6 // goroutine that they're supposed to. 7 8 package goroutine 9 10 import ( 11 "errors" 12 "os" 13 14 "github.com/searKing/golang/go/error/must" 15 ) 16 17 var DebugGoroutines = os.Getenv("DEBUG_GOROUTINES") == "1" 18 19 // Lock represents a goroutine ID, with goroutine ID checked, that is whether GoRoutines of lock newer and check caller differ. 20 // disable when DebugGoroutines equals false 21 type Lock uint64 22 23 // NewLock returns a goroutine Lock, that checks whether goroutine of lock newer and check caller differ. 24 // Code borrowed from https://github.com/golang/go/blob/master/src/net/http/h2_bundle.go 25 func NewLock() Lock { 26 if !DebugGoroutines { 27 return 0 28 } 29 return Lock(ID()) 30 } 31 32 // Check if caller's goroutine is locked 33 func (g Lock) Check() error { 34 if !DebugGoroutines { 35 return nil 36 } 37 if ID() != uint64(g) { 38 return errors.New("running on the wrong goroutine") 39 } 40 return nil 41 } 42 43 func (g Lock) MustCheck() { 44 must.Must(g.Check()) 45 } 46 47 // Check whether caller's goroutine escape lock 48 func (g Lock) CheckNotOn() error { 49 if !DebugGoroutines { 50 return nil 51 } 52 if ID() == uint64(g) { 53 return errors.New("running on the wrong goroutine") 54 } 55 return nil 56 } 57 58 func (g Lock) MustCheckNotOn() { 59 must.Must(g.CheckNotOn()) 60 }