-
Notifications
You must be signed in to change notification settings - Fork 10
/
utils.go
49 lines (41 loc) · 1.35 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
package videoserver
import (
"os"
"reflect"
"sync"
"sync/atomic"
)
// https://github.com/trailofbits/go-mutexasserts/blob/master/mutex.go#L15
const mutexLocked = 1
func RWMutexLocked(rw *sync.RWMutex) bool {
// RWMutex has a "w" sync.Mutex field for write lock
state := reflect.ValueOf(rw).Elem().FieldByName("w").FieldByName("state")
return state.Int()&mutexLocked == mutexLocked
}
func MutexLocked(m *sync.Mutex) bool {
state := reflect.ValueOf(m).Elem().FieldByName("state")
return state.Int()&mutexLocked == mutexLocked
}
func RWMutexRLocked(rw *sync.RWMutex) bool {
return readerCount(rw) > 0
}
// Starting in go1.20, readerCount is an atomic int32 value.
// See: https://go-review.googlesource.com/c/go/+/429767
func readerCount(rw *sync.RWMutex) int64 {
// Look up the address of the readerCount field and use it to create a pointer to an atomic.Int32,
// then load the value to return.
rc := (*atomic.Int32)(reflect.ValueOf(rw).Elem().FieldByName("readerCount").Addr().UnsafePointer())
return int64(rc.Load())
}
// Prior to go1.20, readerCount was an int value.
// func readerCount(rw *sync.RWMutex) int64 {
// return reflect.ValueOf(rw).Elem().FieldByName("readerCount").Int()
// }
// ensureDir alias to 'mkdir -p'
func ensureDir(dirName string) error {
err := os.MkdirAll(dirName, 0777)
if err == nil || os.IsExist(err) {
return nil
}
return err
}