1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-01-08 10:45:04 +02:00
imgproxy/semaphore/semaphore.go
2022-07-20 18:06:26 +06:00

48 lines
751 B
Go

package semaphore
import (
"context"
"sync"
)
type Semaphore struct {
sem chan struct{}
}
func New(n int) *Semaphore {
return &Semaphore{
sem: make(chan struct{}, n),
}
}
func (s *Semaphore) Aquire(ctx context.Context) (*Token, bool) {
select {
case s.sem <- struct{}{}:
return &Token{release: s.release}, true
case <-ctx.Done():
return &Token{release: func() {}}, false
}
}
func (s *Semaphore) TryAquire() (*Token, bool) {
select {
case s.sem <- struct{}{}:
return &Token{release: s.release}, true
default:
return &Token{release: func() {}}, false
}
}
func (s *Semaphore) release() {
<-s.sem
}
type Token struct {
release func()
releaseOnce sync.Once
}
func (t *Token) Release() {
t.releaseOnce.Do(t.release)
}