-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathutils.go
86 lines (65 loc) · 1.66 KB
/
utils.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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package curator
import (
"log"
"sync/atomic"
"unsafe"
)
// A Closeable is a source or destination of data that can be closed.
type Closeable interface {
// Closes this and releases any system resources associated with it.
Close() error
}
func CloseQuietly(closeable Closeable) (err error) {
defer func() {
if v := recover(); v != nil {
log.Printf("panic when closing %s, %v", closeable, v)
err, _ = v.(error)
}
}()
if err = closeable.Close(); err != nil {
log.Printf("fail to close %s, %s", closeable, err)
}
return
}
type AtomicBool int32
const (
FALSE AtomicBool = iota
TRUE
)
func NewAtomicBool(b bool) AtomicBool {
if b {
return TRUE
}
return FALSE
}
func (b *AtomicBool) CompareAndSwap(oldValue, newValue bool) bool {
return atomic.CompareAndSwapInt32((*int32)(unsafe.Pointer(b)), int32(NewAtomicBool(oldValue)), int32(NewAtomicBool(newValue)))
}
func (b *AtomicBool) Load() bool {
return atomic.LoadInt32((*int32)(unsafe.Pointer(b))) != int32(FALSE)
}
func (b *AtomicBool) Swap(v bool) bool {
var n AtomicBool
if v {
n = TRUE
}
return atomic.SwapInt32((*int32)(unsafe.Pointer(b)), int32(n)) != int32(FALSE)
}
func (b *AtomicBool) Set(v bool) { b.Swap(v) }
type State int32
const (
LATENT State = iota // Start() has not yet been called
STARTED // Start() has been called
STOPPED // Close() has been called
)
func (s *State) Change(oldState, newState State) bool {
return atomic.CompareAndSwapInt32((*int32)(s), int32(oldState), int32(newState))
}
func (s *State) Value() State {
return State(atomic.LoadInt32((*int32)(s)))
}
func (s State) Check(state State, msg string) {
if s != state {
panic(msg)
}
}