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  }