refresource.go 892 B

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