69 lines
1.0 KiB
Go
69 lines
1.0 KiB
Go
package rpcx
|
|
|
|
import (
|
|
"reflect"
|
|
"sync"
|
|
)
|
|
|
|
var UsePool bool
|
|
|
|
type Reset interface {
|
|
Reset()
|
|
}
|
|
|
|
var reflectTypePools = &typePools{
|
|
pools: make(map[reflect.Type]*sync.Pool),
|
|
New: func(t reflect.Type) interface{} {
|
|
var argv reflect.Value
|
|
|
|
if t.Kind() == reflect.Ptr { // reply must be ptr
|
|
argv = reflect.New(t.Elem())
|
|
} else {
|
|
argv = reflect.New(t)
|
|
}
|
|
|
|
return argv.Interface()
|
|
},
|
|
}
|
|
|
|
type typePools struct {
|
|
mu sync.RWMutex
|
|
pools map[reflect.Type]*sync.Pool
|
|
New func(t reflect.Type) interface{}
|
|
}
|
|
|
|
func (p *typePools) Init(t reflect.Type) {
|
|
tp := &sync.Pool{}
|
|
tp.New = func() interface{} {
|
|
return p.New(t)
|
|
}
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
p.pools[t] = tp
|
|
}
|
|
|
|
func (p *typePools) Put(t reflect.Type, x interface{}) {
|
|
if !UsePool {
|
|
return
|
|
}
|
|
if o, ok := x.(Reset); ok {
|
|
o.Reset()
|
|
}
|
|
|
|
p.mu.RLock()
|
|
pool := p.pools[t]
|
|
p.mu.RUnlock()
|
|
pool.Put(x)
|
|
}
|
|
|
|
func (p *typePools) Get(t reflect.Type) interface{} {
|
|
if !UsePool {
|
|
return p.New(t)
|
|
}
|
|
p.mu.RLock()
|
|
pool := p.pools[t]
|
|
p.mu.RUnlock()
|
|
|
|
return pool.Get()
|
|
}
|