github.com/lingyao2333/mo-zero@v1.4.1/core/syncx/refresource.go (about) 1 package syncx 2 3 import ( 4 "errors" 5 "sync" 6 ) 7 8 // ErrUseOfCleaned is an error that indicates using a cleaned resource. 9 var ErrUseOfCleaned = errors.New("using a cleaned resource") 10 11 // A RefResource is used to reference counting a resource. 12 type RefResource struct { 13 lock sync.Mutex 14 ref int32 15 cleaned bool 16 clean func() 17 } 18 19 // NewRefResource returns a RefResource. 20 func NewRefResource(clean func()) *RefResource { 21 return &RefResource{ 22 clean: clean, 23 } 24 } 25 26 // Use uses the resource with reference count incremented. 27 func (r *RefResource) Use() error { 28 r.lock.Lock() 29 defer r.lock.Unlock() 30 31 if r.cleaned { 32 return ErrUseOfCleaned 33 } 34 35 r.ref++ 36 return nil 37 } 38 39 // Clean cleans a resource with reference count decremented. 40 func (r *RefResource) Clean() { 41 r.lock.Lock() 42 defer r.lock.Unlock() 43 44 if r.cleaned { 45 return 46 } 47 48 r.ref-- 49 if r.ref == 0 { 50 r.cleaned = true 51 r.clean() 52 } 53 }