| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 | package signalimport (	"context"	"sync"	"time"	"v2ray.com/core/common"	"v2ray.com/core/common/task")type ActivityUpdater interface {	Update()}type ActivityTimer struct {	sync.RWMutex	updated   chan struct{}	checkTask *task.Periodic	onTimeout func()}func (t *ActivityTimer) Update() {	select {	case t.updated <- struct{}{}:	default:	}}func (t *ActivityTimer) check() error {	select {	case <-t.updated:	default:		t.finish()	}	return nil}func (t *ActivityTimer) finish() {	t.Lock()	defer t.Unlock()	if t.onTimeout != nil {		t.onTimeout()		t.onTimeout = nil	}	if t.checkTask != nil {		t.checkTask.Close() // nolint: errcheck		t.checkTask = nil	}}func (t *ActivityTimer) SetTimeout(timeout time.Duration) {	if timeout == 0 {		t.finish()		return	}	checkTask := &task.Periodic{		Interval: timeout,		Execute:  t.check,	}	t.Lock()	if t.checkTask != nil {		t.checkTask.Close() // nolint: errcheck	}	t.checkTask = checkTask	t.Unlock()	t.Update()	common.Must(checkTask.Start())}func CancelAfterInactivity(ctx context.Context, cancel context.CancelFunc, timeout time.Duration) *ActivityTimer {	timer := &ActivityTimer{		updated:   make(chan struct{}, 1),		onTimeout: cancel,	}	timer.SetTimeout(timeout)	return timer}
 |