forked from go-eden/routine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroutine_api.go
86 lines (73 loc) · 2.35 KB
/
routine_api.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package routine
import "fmt"
// LocalStorage provides goroutine-local variables.
type LocalStorage interface {
// Get returns the value in the current goroutine's local storage, if it was set before.
Get() (value interface{})
// Set copy the value into the current goroutine's local storage, and return the old value.
Set(value interface{}) (oldValue interface{})
// Del delete the value from the current goroutine's local storage, and return it.
Del() (oldValue interface{})
// Clear delete values from all goroutine's local storages.
Clear()
}
// ImmutableContext represents all local storages of one goroutine.
type ImmutableContext struct {
gid int64
values map[uintptr]interface{}
}
// Go start an new goroutine, and copy all local storages from current goroutine.
func Go(f func()) {
ic := BackupContext()
go func() {
InheritContext(ic)
f()
}()
}
// BackupContext copy all local storages into an ImmutableContext instance.
func BackupContext() *ImmutableContext {
s := loadCurrentStore()
data := make(map[uintptr]interface{}, len(s.values))
for k, v := range s.values {
data[k] = v
}
return &ImmutableContext{gid: s.gid, values: data}
}
// InheritContext load the specified ImmutableContext instance into the local storage of current goroutine.
func InheritContext(ic *ImmutableContext) {
if ic == nil || ic.values == nil {
return
}
s := loadCurrentStore()
for k, v := range ic.values {
s.values[k] = v
}
}
// NewLocalStorage create and return an new LocalStorage instance.
func NewLocalStorage() LocalStorage {
t := new(storage)
t.Clear()
return t
}
// Goid return the current goroutine's unique id.
// It will try get gid by native cgo/asm for better performance,
// and could parse gid from stack for failover supporting.
func Goid() (id int64) {
var succ bool
if id, succ = getGoidByNative(); !succ {
// no need to warning
id = getGoidByStack()
}
return
}
// AllGoids return all goroutine's goid in the current golang process.
// It will try load all goid from runtime natively for better performance,
// and fallover to runtime.Stack, which is realy inefficient.
func AllGoids() (ids []int64) {
var err error
if ids, err = getAllGoidByNative(); err != nil {
fmt.Println("[WARNING] cannot get all goid from runtime natively, now fallover to stack info, this will be very inefficient!!!")
ids = getAllGoidByStack()
}
return
}