refresource.go 600 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. package syncx
  2. import (
  3. "errors"
  4. "sync"
  5. )
  6. var ErrUseOfCleaned = errors.New("using a cleaned resource")
  7. type RefResource struct {
  8. lock sync.Mutex
  9. ref int32
  10. cleaned bool
  11. clean func()
  12. }
  13. func NewRefResource(clean func()) *RefResource {
  14. return &RefResource{
  15. clean: clean,
  16. }
  17. }
  18. func (r *RefResource) Use() error {
  19. r.lock.Lock()
  20. defer r.lock.Unlock()
  21. if r.cleaned {
  22. return ErrUseOfCleaned
  23. }
  24. r.ref++
  25. return nil
  26. }
  27. func (r *RefResource) Clean() {
  28. r.lock.Lock()
  29. defer r.lock.Unlock()
  30. if r.cleaned {
  31. return
  32. }
  33. r.ref--
  34. if r.ref == 0 {
  35. r.cleaned = true
  36. r.clean()
  37. }
  38. }