gitea/vendor/github.com/ngaut/sync2/semaphore.go

56 lines
1.3 KiB
Go

// Copyright 2012, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package sync2
// What's in a name? Channels have all you need to emulate a counting
// semaphore with a boatload of extra functionality. However, in some
// cases, you just want a familiar API.
import (
"time"
)
// Semaphore is a counting semaphore with the option to
// specify a timeout.
type Semaphore struct {
slots chan struct{}
timeout time.Duration
}
// NewSemaphore creates a Semaphore. The count parameter must be a positive
// number. A timeout of zero means that there is no timeout.
func NewSemaphore(count int, timeout time.Duration) *Semaphore {
sem := &Semaphore{
slots: make(chan struct{}, count),
timeout: timeout,
}
for i := 0; i < count; i++ {
sem.slots <- struct{}{}
}
return sem
}
// Acquire returns true on successful acquisition, and
// false on a timeout.
func (sem *Semaphore) Acquire() bool {
if sem.timeout == 0 {
<-sem.slots
return true
}
select {
case <-sem.slots:
return true
case <-time.After(sem.timeout):
return false
}
}
// Release releases the acquired semaphore. You must
// not release more than the number of semaphores you've
// acquired.
func (sem *Semaphore) Release() {
sem.slots <- struct{}{}
}