-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsemaphore.go
43 lines (35 loc) · 954 Bytes
/
semaphore.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package foundation
type Semaphore interface {
// Acquire tries to get a lock and blocks until it does
Acquire()
// GetAcquireChannel returns the inner channel to be used to acquire a lock within a select statement
GetAcquireChannel() chan struct{}
// Release releases a lock
Release()
// Wait until all locks are released
Wait()
}
type semaphore struct {
semaphoreChannel chan struct{}
}
func NewSemaphore(maxConcurrency int) Semaphore {
return &semaphore{
semaphoreChannel: make(chan struct{}, maxConcurrency),
}
}
func (s *semaphore) Acquire() {
s.semaphoreChannel <- struct{}{}
}
func (s *semaphore) GetAcquireChannel() chan struct{} {
return s.semaphoreChannel
}
func (s *semaphore) Release() {
<-s.semaphoreChannel
}
func (s *semaphore) Wait() {
for i := 0; i < cap(s.semaphoreChannel); i++ {
s.Acquire()
}
// reset so the semaphore can be used again
s.semaphoreChannel = make(chan struct{}, cap(s.semaphoreChannel))
}