Add pause manager

This commit is contained in:
世界 2023-08-07 16:02:48 +08:00
parent a755de3bbd
commit 4db0062caa
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
3 changed files with 135 additions and 0 deletions

22
service/pause/context.go Normal file
View file

@ -0,0 +1,22 @@
package pause
import (
"context"
"github.com/sagernet/sing/service"
)
func ManagerFromContext(ctx context.Context) Manager {
return service.FromContext[Manager](ctx)
}
func ContextWithManager(ctx context.Context, manager Manager) context.Context {
return service.ContextWith[Manager](ctx, manager)
}
func ContextWithDefaultManager(ctx context.Context) context.Context {
if service.FromContext[Manager](ctx) != nil {
return ctx
}
return service.ContextWith[Manager](ctx, NewDefaultManager(ctx))
}

101
service/pause/default.go Normal file
View file

@ -0,0 +1,101 @@
package pause
import (
"context"
"sync"
)
type defaultManager struct {
ctx context.Context
access sync.Mutex
devicePause chan struct{}
networkPause chan struct{}
}
func NewDefaultManager(ctx context.Context) Manager {
devicePauseChan := make(chan struct{})
networkPauseChan := make(chan struct{})
close(devicePauseChan)
close(networkPauseChan)
return &defaultManager{
ctx: ctx,
devicePause: devicePauseChan,
networkPause: networkPauseChan,
}
}
func (d *defaultManager) DevicePause() {
d.access.Lock()
defer d.access.Unlock()
select {
case <-d.devicePause:
d.devicePause = make(chan struct{})
default:
}
}
func (d *defaultManager) DeviceWake() {
d.access.Lock()
defer d.access.Unlock()
select {
case <-d.devicePause:
default:
close(d.devicePause)
}
}
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.networkPause = make(chan struct{})
default:
}
}
func (d *defaultManager) NetworkWake() {
d.access.Lock()
defer d.access.Unlock()
select {
case <-d.networkPause:
default:
close(d.networkPause)
}
}
func (d *defaultManager) NetworkPauseChan() <-chan struct{} {
return d.networkPause
}
func (d *defaultManager) IsPaused() bool {
select {
case <-d.devicePause:
default:
return true
}
select {
case <-d.networkPause:
default:
return true
}
return false
}
func (d *defaultManager) WaitActive() {
select {
case <-d.devicePause:
case <-d.ctx.Done():
}
select {
case <-d.networkPause:
case <-d.ctx.Done():
}
}

12
service/pause/manager.go Normal file
View file

@ -0,0 +1,12 @@
package pause
type Manager interface {
DevicePause()
DeviceWake()
DevicePauseChan() <-chan struct{}
NetworkPause()
NetworkWake()
NetworkPauseChan() <-chan struct{}
IsPaused() bool
WaitActive()
}