Updated everything for dependencies. All sub packages are now part of the project. This was a massive update, hopefully won't have to be reverted.
This commit is contained in:
64
gumble/go-opus/streams_map.go
Normal file
64
gumble/go-opus/streams_map.go
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright © Go Opus Authors (see AUTHORS file)
|
||||
//
|
||||
// License for use of this code is detailed in the LICENSE file
|
||||
|
||||
// +build !nolibopusfile
|
||||
|
||||
package opus
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// A map of simple integers to the actual pointers to stream structs. Avoids
|
||||
// passing pointers into the Go heap to C.
|
||||
//
|
||||
// As per the CGo pointers design doc for go 1.6:
|
||||
//
|
||||
// A particular unsafe area is C code that wants to hold on to Go func and
|
||||
// pointer values for future callbacks from C to Go. This works today but is not
|
||||
// permitted by the invariant. It is hard to detect. One safe approach is: Go
|
||||
// code that wants to preserve funcs/pointers stores them into a map indexed by
|
||||
// an int. Go code calls the C code, passing the int, which the C code may store
|
||||
// freely. When the C code wants to call into Go, it passes the int to a Go
|
||||
// function that looks in the map and makes the call. An explicit call is
|
||||
// required to release the value from the map if it is no longer needed, but
|
||||
// that was already true before.
|
||||
//
|
||||
// - https://github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md
|
||||
type streamsMap struct {
|
||||
sync.RWMutex
|
||||
m map[uintptr]*Stream
|
||||
counter uintptr
|
||||
}
|
||||
|
||||
func (sm *streamsMap) Get(id uintptr) *Stream {
|
||||
sm.RLock()
|
||||
defer sm.RUnlock()
|
||||
return sm.m[id]
|
||||
}
|
||||
|
||||
func (sm *streamsMap) Del(s *Stream) {
|
||||
sm.Lock()
|
||||
defer sm.Unlock()
|
||||
delete(sm.m, s.id)
|
||||
}
|
||||
|
||||
// NextId returns a unique ID for each call.
|
||||
func (sm *streamsMap) NextId() uintptr {
|
||||
return atomic.AddUintptr(&sm.counter, 1)
|
||||
}
|
||||
|
||||
func (sm *streamsMap) Save(s *Stream) {
|
||||
sm.Lock()
|
||||
defer sm.Unlock()
|
||||
sm.m[s.id] = s
|
||||
}
|
||||
|
||||
func newStreamsMap() *streamsMap {
|
||||
return &streamsMap{
|
||||
counter: 0,
|
||||
m: map[uintptr]*Stream{},
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user