mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-04-29 06:35:07 +03:00
get rid of session workers, new util.PutBytes/GetBytes logic
This commit is contained in:
parent
39245f8134
commit
e0a3055c2f
6 changed files with 100 additions and 109 deletions
|
@ -13,33 +13,25 @@ type Cancellation interface {
|
|||
Error() error
|
||||
}
|
||||
|
||||
var CancellationFinalized = errors.New("finalizer called")
|
||||
var CancellationTimeoutError = errors.New("timeout")
|
||||
|
||||
func CancellationFinalizer(c Cancellation) {
|
||||
c.Cancel(errors.New("finalizer called"))
|
||||
c.Cancel(CancellationFinalized)
|
||||
}
|
||||
|
||||
type cancellation struct {
|
||||
signal chan error
|
||||
cancel chan struct{}
|
||||
errMtx sync.RWMutex
|
||||
mutex sync.RWMutex
|
||||
err error
|
||||
}
|
||||
|
||||
func (c *cancellation) worker() {
|
||||
// Launch this in a separate goroutine when creating a cancellation
|
||||
err := <-c.signal
|
||||
c.errMtx.Lock()
|
||||
c.err = err
|
||||
c.errMtx.Unlock()
|
||||
close(c.cancel)
|
||||
done bool
|
||||
}
|
||||
|
||||
func NewCancellation() Cancellation {
|
||||
c := cancellation{
|
||||
signal: make(chan error),
|
||||
cancel: make(chan struct{}),
|
||||
}
|
||||
runtime.SetFinalizer(&c, CancellationFinalizer)
|
||||
go c.worker()
|
||||
return &c
|
||||
}
|
||||
|
||||
|
@ -48,18 +40,22 @@ func (c *cancellation) Finished() <-chan struct{} {
|
|||
}
|
||||
|
||||
func (c *cancellation) Cancel(err error) error {
|
||||
select {
|
||||
case c.signal <- err:
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
if c.done {
|
||||
return c.err
|
||||
} else {
|
||||
c.err = err
|
||||
c.done = true
|
||||
close(c.cancel)
|
||||
return nil
|
||||
case <-c.cancel:
|
||||
return c.Error()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *cancellation) Error() error {
|
||||
c.errMtx.RLock()
|
||||
c.mutex.RLock()
|
||||
err := c.err
|
||||
c.errMtx.RUnlock()
|
||||
c.mutex.RUnlock()
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -75,8 +71,6 @@ func CancellationChild(parent Cancellation) Cancellation {
|
|||
return child
|
||||
}
|
||||
|
||||
var CancellationTimeoutError = errors.New("timeout")
|
||||
|
||||
func CancellationWithTimeout(parent Cancellation, timeout time.Duration) Cancellation {
|
||||
child := CancellationChild(parent)
|
||||
go func() {
|
||||
|
|
|
@ -3,6 +3,7 @@ package util
|
|||
// These are misc. utility functions that didn't really fit anywhere else
|
||||
|
||||
import "runtime"
|
||||
import "sync"
|
||||
import "time"
|
||||
|
||||
// A wrapper around runtime.Gosched() so it doesn't need to be imported elsewhere.
|
||||
|
@ -21,29 +22,27 @@ func UnlockThread() {
|
|||
}
|
||||
|
||||
// This is used to buffer recently used slices of bytes, to prevent allocations in the hot loops.
|
||||
// It's used like a sync.Pool, but with a fixed size and typechecked without type casts to/from interface{} (which were making the profiles look ugly).
|
||||
var byteStore chan []byte
|
||||
var byteStoreMutex sync.Mutex
|
||||
var byteStore [][]byte
|
||||
|
||||
func init() {
|
||||
byteStore = make(chan []byte, 32)
|
||||
}
|
||||
|
||||
// Gets an empty slice from the byte store, if one is available, or else returns a new nil slice.
|
||||
// Gets an empty slice from the byte store.
|
||||
func GetBytes() []byte {
|
||||
select {
|
||||
case bs := <-byteStore:
|
||||
return bs[:0]
|
||||
default:
|
||||
byteStoreMutex.Lock()
|
||||
defer byteStoreMutex.Unlock()
|
||||
if len(byteStore) > 0 {
|
||||
var bs []byte
|
||||
bs, byteStore = byteStore[len(byteStore)-1][:0], byteStore[:len(byteStore)-1]
|
||||
return bs
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Puts a slice in the store, if there's room, or else returns and lets the slice get collected.
|
||||
// Puts a slice in the store.
|
||||
func PutBytes(bs []byte) {
|
||||
select {
|
||||
case byteStore <- bs:
|
||||
default:
|
||||
}
|
||||
byteStoreMutex.Lock()
|
||||
defer byteStoreMutex.Unlock()
|
||||
byteStore = append(byteStore, bs)
|
||||
}
|
||||
|
||||
// This is a workaround to go's broken timer implementation
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue