blob: 1acde76b0686dd6aade44b80c66ae58e691a574c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package common
import (
"sync"
)
// A simple lock-and-condition-variable based semaphore implementation.
type Semaphore struct {
lock sync.Mutex
cond *sync.Cond
count int64
}
func NewSemaphore(count int64) *Semaphore {
sem := &Semaphore{
count: int64(count),
}
sem.cond = &sync.Cond{
L: &sem.lock,
}
return sem
}
func (sem *Semaphore) Post() {
sem.lock.Lock()
sem.count++
if sem.count > 0 {
sem.cond.Broadcast()
}
sem.lock.Unlock()
}
func (sem *Semaphore) Posts(amt int64) {
sem.lock.Lock()
sem.count += amt
if sem.count > 0 {
sem.cond.Broadcast()
}
sem.lock.Unlock()
}
func (sem *Semaphore) Wait() {
sem.lock.Lock()
for {
if sem.count > 0 {
sem.count--
sem.lock.Unlock()
return
}
sem.cond.Wait()
}
}
func (sem *Semaphore) Waits(amt int64) {
var i int64
for i = 0; i < amt; i++ {
sem.Wait()
}
}