-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathsemaphore.go
59 lines (50 loc) · 1.42 KB
/
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// Semaphore implementation that adds so necessary synchronization
// primitive into Go language. It uses built-in channel with empty struct
// so it doesn't utilize a lot of memory to buffer acquired elements.
package nsync
import "time"
// Semaphore implementation uses built in channel using 0 size struct values.
type Semaphore struct {
sch chan struct{}
}
// NewSemaphore returns an instance of a semaphore.
func NewSemaphore(value int) *Semaphore {
return &Semaphore{
sch: make(chan struct{}, value),
}
}
// Acquire tries to acquire semaphore lock. If no luck it will block.
func (s *Semaphore) Acquire() {
s.sch <- struct{}{}
}
// Release releases acquired semaphore. If semaphore is not acquired it will panic.
func (s *Semaphore) Release() {
select {
case <-s.sch:
default:
panic("No semaphore locks!")
}
}
// TryAcquire tries to acquire semaphore. Returns true/false if success/failure accordingly.
func (s *Semaphore) TryAcquire() bool {
select {
case s.sch <- struct{}{}:
return true
default:
return false
}
}
// TryAcquireTimeout tries to acquire semaphore for a specified time interval.
// Returns true/false if success/failure accordingly.
func (s *Semaphore) TryAcquireTimeout(d time.Duration) bool {
select {
case s.sch <- struct{}{}:
return true
case <-time.After(d):
return false
}
}
// Value returns the number of currently acquired semaphores.
func (s *Semaphore) Value() int {
return len(s.sch)
}