timeoutlimit.go 724 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. package syncx
  2. import (
  3. "errors"
  4. "time"
  5. )
  6. var ErrTimeout = errors.New("borrow timeout")
  7. type TimeoutLimit struct {
  8. limit Limit
  9. cond *Cond
  10. }
  11. func NewTimeoutLimit(n int) TimeoutLimit {
  12. return TimeoutLimit{
  13. limit: NewLimit(n),
  14. cond: NewCond(),
  15. }
  16. }
  17. func (l TimeoutLimit) Borrow(timeout time.Duration) error {
  18. if l.TryBorrow() {
  19. return nil
  20. }
  21. var ok bool
  22. for {
  23. timeout, ok = l.cond.WaitWithTimeout(timeout)
  24. if ok && l.TryBorrow() {
  25. return nil
  26. }
  27. if timeout <= 0 {
  28. return ErrTimeout
  29. }
  30. }
  31. }
  32. func (l TimeoutLimit) Return() error {
  33. if err := l.limit.Return(); err != nil {
  34. return err
  35. }
  36. l.cond.Signal()
  37. return nil
  38. }
  39. func (l TimeoutLimit) TryBorrow() bool {
  40. return l.limit.TryBorrow()
  41. }