mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-28 00:24:19 +00:00
1c0b76c27a
Minor refactors across the codebase to improve readability and use more efficient APIs: replace fmt.Sprintf+base64 encoding with fmt.Appendf when building Shadowsocks userInfo; compute elapsed using max(now-prev.at, window) to simplify logic; use strings.SplitSeq for splitting in two places; simplify test and goroutine loops to range-based iterations and use errgroup's Go helper; and align/clean up struct field formatting and test map literals. Mostly stylistic/efficiency changes with no intended behavior changes.
57 lines
1.1 KiB
Go
57 lines
1.1 KiB
Go
package xray
|
|
|
|
import (
|
|
"errors"
|
|
"os/exec"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// TestProcessLifecycleFieldsRaceSafe drives the lifecycle fields (cmd, done,
|
|
// exitErr) the way Start/startCommand and the waitForCommand goroutine do, while
|
|
// the status getters read them concurrently. Run with -race: any unsynchronized
|
|
// access to those fields is reported as a data race.
|
|
func TestProcessLifecycleFieldsRaceSafe(t *testing.T) {
|
|
p := &process{logWriter: NewLogWriter()}
|
|
|
|
var wg sync.WaitGroup
|
|
stop := make(chan struct{})
|
|
|
|
// Writer: churn cmd/done/exitErr like Start + waitForCommand.
|
|
wg.Go(func() {
|
|
for {
|
|
select {
|
|
case <-stop:
|
|
return
|
|
default:
|
|
}
|
|
p.mu.Lock()
|
|
p.cmd = &exec.Cmd{}
|
|
p.done = make(chan struct{})
|
|
p.mu.Unlock()
|
|
p.setExitErr(errors.New("boom"))
|
|
}
|
|
})
|
|
|
|
// Readers: the concurrent status getters.
|
|
for range 4 {
|
|
wg.Go(func() {
|
|
for {
|
|
select {
|
|
case <-stop:
|
|
return
|
|
default:
|
|
}
|
|
_ = p.IsRunning()
|
|
_ = p.GetErr()
|
|
_ = p.GetResult()
|
|
}
|
|
})
|
|
}
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
close(stop)
|
|
wg.Wait()
|
|
}
|