mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-04 04:17:38 +03:00
Improve pause manager
This commit is contained in:
parent
81d1bc2768
commit
cdb9908442
2 changed files with 57 additions and 12 deletions
|
@ -3,13 +3,19 @@ package pause
|
|||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/sagernet/sing/common/atomic"
|
||||
"github.com/sagernet/sing/common/x/list"
|
||||
)
|
||||
|
||||
type defaultManager struct {
|
||||
ctx context.Context
|
||||
access sync.Mutex
|
||||
devicePause chan struct{}
|
||||
networkPause chan struct{}
|
||||
ctx context.Context
|
||||
access sync.Mutex
|
||||
devicePause chan struct{}
|
||||
devicePaused atomic.Bool
|
||||
networkPause chan struct{}
|
||||
networkPaused atomic.Bool
|
||||
callbacks list.List[Callback]
|
||||
}
|
||||
|
||||
func NewDefaultManager(ctx context.Context) Manager {
|
||||
|
@ -29,7 +35,9 @@ func (d *defaultManager) DevicePause() {
|
|||
defer d.access.Unlock()
|
||||
select {
|
||||
case <-d.devicePause:
|
||||
d.devicePaused.Store(true)
|
||||
d.devicePause = make(chan struct{})
|
||||
d.emit(EventDevicePaused)
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
@ -40,20 +48,20 @@ func (d *defaultManager) DeviceWake() {
|
|||
select {
|
||||
case <-d.devicePause:
|
||||
default:
|
||||
d.devicePaused.Store(false)
|
||||
close(d.devicePause)
|
||||
d.emit(EventDeviceWake)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *defaultManager) DevicePauseChan() <-chan struct{} {
|
||||
return d.devicePause
|
||||
}
|
||||
|
||||
func (d *defaultManager) NetworkPause() {
|
||||
d.access.Lock()
|
||||
defer d.access.Unlock()
|
||||
select {
|
||||
case <-d.networkPause:
|
||||
d.networkPaused.Store(true)
|
||||
d.networkPause = make(chan struct{})
|
||||
d.emit(EventNetworkPause)
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
@ -64,12 +72,30 @@ func (d *defaultManager) NetworkWake() {
|
|||
select {
|
||||
case <-d.networkPause:
|
||||
default:
|
||||
d.networkPaused.Store(false)
|
||||
close(d.networkPause)
|
||||
d.emit(EventNetworkWake)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *defaultManager) NetworkPauseChan() <-chan struct{} {
|
||||
return d.networkPause
|
||||
func (d *defaultManager) RegisterCallback(callback Callback) *list.Element[Callback] {
|
||||
d.access.Lock()
|
||||
defer d.access.Unlock()
|
||||
return d.callbacks.PushBack(callback)
|
||||
}
|
||||
|
||||
func (d *defaultManager) UnregisterCallback(element *list.Element[Callback]) {
|
||||
d.access.Lock()
|
||||
defer d.access.Unlock()
|
||||
d.callbacks.Remove(element)
|
||||
}
|
||||
|
||||
func (d *defaultManager) IsDevicePaused() bool {
|
||||
return d.devicePaused.Load()
|
||||
}
|
||||
|
||||
func (d *defaultManager) IsNetworkPaused() bool {
|
||||
return d.networkPaused.Load()
|
||||
}
|
||||
|
||||
func (d *defaultManager) IsPaused() bool {
|
||||
|
@ -99,3 +125,9 @@ func (d *defaultManager) WaitActive() {
|
|||
case <-d.ctx.Done():
|
||||
}
|
||||
}
|
||||
|
||||
func (d *defaultManager) emit(event int) {
|
||||
for element := d.callbacks.Front(); element != nil; element = element.Next() {
|
||||
element.Value(event)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,25 @@
|
|||
package pause
|
||||
|
||||
import "github.com/sagernet/sing/common/x/list"
|
||||
|
||||
type Manager interface {
|
||||
DevicePause()
|
||||
DeviceWake()
|
||||
DevicePauseChan() <-chan struct{}
|
||||
NetworkPause()
|
||||
NetworkWake()
|
||||
NetworkPauseChan() <-chan struct{}
|
||||
IsDevicePaused() bool
|
||||
IsNetworkPaused() bool
|
||||
IsPaused() bool
|
||||
WaitActive()
|
||||
RegisterCallback(callback Callback) *list.Element[Callback]
|
||||
UnregisterCallback(element *list.Element[Callback])
|
||||
}
|
||||
|
||||
const (
|
||||
EventDevicePaused int = iota
|
||||
EventDeviceWake
|
||||
EventNetworkPause
|
||||
EventNetworkWake
|
||||
)
|
||||
|
||||
type Callback = func(event int)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue