diff options
Diffstat (limited to 'cli/internal/util/semaphore.go')
| -rw-r--r-- | cli/internal/util/semaphore.go | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/cli/internal/util/semaphore.go b/cli/internal/util/semaphore.go new file mode 100644 index 0000000..ef29df0 --- /dev/null +++ b/cli/internal/util/semaphore.go @@ -0,0 +1,43 @@ +package util + +// Semaphore is a wrapper around a channel to provide +// utility methods to clarify that we are treating the +// channel as a semaphore +type Semaphore chan struct{} + +// NewSemaphore creates a semaphore that allows up +// to a given limit of simultaneous acquisitions +func NewSemaphore(n int) Semaphore { + if n <= 0 { + panic("semaphore with limit <=0") + } + ch := make(chan struct{}, n) + return Semaphore(ch) +} + +// Acquire is used to acquire an available slot. +// Blocks until available. +func (s Semaphore) Acquire() { + s <- struct{}{} +} + +// TryAcquire is used to do a non-blocking acquire. +// Returns a bool indicating success +func (s Semaphore) TryAcquire() bool { + select { + case s <- struct{}{}: + return true + default: + return false + } +} + +// Release is used to return a slot. Acquire must +// be called as a pre-condition. +func (s Semaphore) Release() { + select { + case <-s: + default: + panic("release without an acquire") + } +} |
