managedresource.go 861 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. package syncx
  2. import "sync"
  3. type ManagedResource struct {
  4. resource interface{}
  5. lock sync.RWMutex
  6. generate func() interface{}
  7. equals func(a, b interface{}) bool
  8. }
  9. func NewManagedResource(generate func() interface{}, equals func(a, b interface{}) bool) *ManagedResource {
  10. return &ManagedResource{
  11. generate: generate,
  12. equals: equals,
  13. }
  14. }
  15. func (mr *ManagedResource) MarkBroken(resource interface{}) {
  16. mr.lock.Lock()
  17. defer mr.lock.Unlock()
  18. if mr.equals(mr.resource, resource) {
  19. mr.resource = nil
  20. }
  21. }
  22. func (mr *ManagedResource) Take() interface{} {
  23. mr.lock.RLock()
  24. resource := mr.resource
  25. mr.lock.RUnlock()
  26. if resource != nil {
  27. return resource
  28. }
  29. mr.lock.Lock()
  30. defer mr.lock.Unlock()
  31. // maybe another Take() call already generated the resource.
  32. if mr.resource == nil {
  33. mr.resource = mr.generate()
  34. }
  35. return mr.resource
  36. }