1 Star 1 Fork 0

D10.天地弦 / gobase

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
objref.go 3.41 KB
一键复制 编辑 原始数据 按行查看 历史
package gobase
import (
"io"
"sort"
"sync"
"sync/atomic"
)
type IStatusGet interface {
GetStatus(args StrMap) string
}
type ICheckStart interface {
CheckStart() error
}
type ObjectInnerRef struct {
refN int32
owner *ConnectObjectRefStorage
connstr string
inner interface{}
}
func (this *ObjectInnerRef) GetObject() interface{} {
return this.inner
}
func (this *ObjectInnerRef) CheckStart() error {
if lvintf, ok := this.inner.(ICheckStart); ok {
return lvintf.CheckStart()
}
return ErrUnsupported
}
func (this *ObjectInnerRef) ReleaseRef() int {
n := atomic.AddInt32(&this.refN, -1)
if n == 0 {
delflag := 0
owner := this.owner
owner.lk.Lock()
if atomic.LoadInt32(&this.refN) == 0 {
delete(owner.lst, this.connstr)
delflag = 1
}
owner.lk.Unlock()
if delflag == 1 {
obj := this.inner
this.inner = nil
if intf, ok := obj.(io.Closer); ok {
go intf.Close()
}
return 1
}
}
return 0
}
// 连接对象管理,
// 借出去对象被+1, 归还-1 =0:释放
type ConnectObjectRefStorage struct {
lk sync.RWMutex
lst map[string]*ObjectInnerRef
newfunc func(connstr string) interface{}
}
func NewConnectObjectRefStorage(newfun func(connstr string) interface{}) *ConnectObjectRefStorage {
rval := &ConnectObjectRefStorage{
newfunc: newfun,
lst: make(map[string]*ObjectInnerRef),
}
return rval
}
func (this *ConnectObjectRefStorage) Range(filter func(obj interface{}) bool, lessfn func(iobj, jobj interface{}) bool, fn func(obj interface{}) bool) {
var lst []interface{}
this.lk.RLock()
for _, v := range this.lst {
vobj := v.GetObject()
if filter != nil {
if filter(vobj) {
lst = append(lst, vobj)
}
} else {
lst = append(lst, vobj)
}
}
this.lk.RUnlock()
if lessfn != nil {
sort.Slice(lst, func(i, j int) bool {
return lessfn(lst[i], lst[j])
})
}
if fn != nil {
for i := 0; i < len(lst); i++ {
v := lst[i]
if !fn(v) {
break
}
}
}
}
func (this *ConnectObjectRefStorage) GetStatus(args ...string) string {
argsMap := NewStrMap()
argsMap.ParseCmdArgs(args)
var sb BytesBuilder
var lst []*ObjectInnerRef
this.lk.RLock()
for _, v := range this.lst {
lst = append(lst, v)
}
this.lk.RUnlock()
sort.Slice(lst, func(i, j int) bool {
return lst[i].connstr < lst[j].connstr
})
for i := 0; i < len(lst); i++ {
v := lst[i]
if lvintf, ok := v.inner.(IStatusGet); ok {
sb.Appendf("connstr:%s\nref:%d\n:status:%s\n\n", v.connstr, v.refN, lvintf.GetStatus(argsMap))
} else {
sb.Appendf("connstr:%s\nref:%d\n\n", v.connstr, v.refN)
}
}
return sb.String()
}
func (this *ConnectObjectRefStorage) CheckGetRef(connstr string) *ObjectInnerRef {
this.lk.RLock()
itm := this.lst[connstr]
if itm != nil {
atomic.AddInt32(&itm.refN, 1)
}
this.lk.RUnlock()
if itm == nil {
this.lk.Lock()
itm = this.lst[connstr]
if itm == nil {
itm = &ObjectInnerRef{
connstr: connstr,
owner: this,
inner: this.newfunc(connstr),
}
this.lst[connstr] = itm
}
atomic.AddInt32(&itm.refN, 1)
this.lk.Unlock()
}
return itm
}
func (this *ConnectObjectRefStorage) ReleaseRef(itm *ObjectInnerRef) {
n := atomic.AddInt32(&itm.refN, -1)
if n == 0 {
delflag := 0
this.lk.Lock()
if atomic.LoadInt32(&itm.refN) == 0 {
delete(this.lst, itm.connstr)
delflag = 1
}
this.lk.Unlock()
if delflag == 1 {
obj := itm.inner
itm.inner = nil
if intf, ok := obj.(io.Closer); ok {
go intf.Close()
}
}
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ymofen/gobase.git
git@gitee.com:ymofen/gobase.git
ymofen
gobase
gobase
v1.2.24053

搜索帮助

344bd9b3 5694891 D2dac590 5694891