mirror of
https://github.com/imgproxy/imgproxy.git
synced 2024-11-24 08:12:38 +02:00
48 lines
753 B
Go
48 lines
753 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) Acquire(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) TryAcquire() (*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)
|
|
}
|