| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 | 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	}	t.Lock()	if t.checkTask != nil {		t.checkTask.Close() // nolint: errcheck	}	t.checkTask = &task.Periodic{		Interval: timeout,		Execute:  t.check,	}	t.Unlock()	t.Update()	common.Must(t.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}
 |