2022-06-12 15:45:34 +00:00
|
|
|
// Package sema implements semaphores.
|
|
|
|
package sema
|
|
|
|
|
|
|
|
import (
|
2023-04-07 21:02:35 +00:00
|
|
|
"github.com/restic/restic/internal/debug"
|
2022-06-12 15:45:34 +00:00
|
|
|
"github.com/restic/restic/internal/errors"
|
|
|
|
)
|
|
|
|
|
2023-04-07 21:02:35 +00:00
|
|
|
// A semaphore limits access to a restricted resource.
|
|
|
|
type semaphore struct {
|
2022-06-12 15:45:34 +00:00
|
|
|
ch chan struct{}
|
|
|
|
}
|
|
|
|
|
2023-04-07 21:02:35 +00:00
|
|
|
// newSemaphore returns a new semaphore with capacity n.
|
|
|
|
func newSemaphore(n uint) (semaphore, error) {
|
2022-06-12 15:45:34 +00:00
|
|
|
if n == 0 {
|
2023-04-07 21:02:35 +00:00
|
|
|
return semaphore{}, errors.New("capacity must be a positive number")
|
2022-06-12 15:45:34 +00:00
|
|
|
}
|
2023-04-07 21:02:35 +00:00
|
|
|
return semaphore{
|
2022-06-12 15:45:34 +00:00
|
|
|
ch: make(chan struct{}, n),
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetToken blocks until a Token is available.
|
2023-04-07 21:02:35 +00:00
|
|
|
func (s semaphore) GetToken() {
|
|
|
|
s.ch <- struct{}{}
|
|
|
|
debug.Log("acquired token")
|
2022-06-12 15:45:34 +00:00
|
|
|
}
|
|
|
|
|
2023-04-07 21:02:35 +00:00
|
|
|
// ReleaseToken returns a token.
|
|
|
|
func (s semaphore) ReleaseToken() { <-s.ch }
|