Skip to content

Commit ad69ee8

Browse files
committed
chore: cleanup ntp code
1 parent dd7b3c2 commit ad69ee8

2 files changed

Lines changed: 46 additions & 49 deletions

File tree

hub/executor/executor.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ func updateNTP(c *config.NTP) {
231231
c.DialerProxy,
232232
c.WriteToSystem,
233233
)
234+
} else {
235+
ntp.ReCreateNTPService("", 0, "", false)
234236
}
235237
}
236238

ntp/service.go

Lines changed: 44 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package ntp
33
import (
44
"context"
55
"sync"
6+
"sync/atomic"
67
"time"
78

89
"github.com/metacubex/mihomo/component/dialer"
@@ -13,24 +14,29 @@ import (
1314
"github.com/metacubex/sing/common/ntp"
1415
)
1516

16-
var offset time.Duration
17-
var service *Service
17+
var globalSrv atomic.Pointer[Service]
18+
var globalMu sync.Mutex
1819

1920
type Service struct {
2021
server M.Socksaddr
2122
dialer proxydialer.SingDialer
2223
ticker *time.Ticker
2324
ctx context.Context
2425
cancel context.CancelFunc
25-
mu sync.Mutex
26+
offset atomic.Int64 // [time.Duration]
2627
syncSystemTime bool
27-
running bool
2828
}
2929

3030
func ReCreateNTPService(server string, interval time.Duration, dialerProxy string, syncSystemTime bool) {
31+
globalMu.Lock()
32+
defer globalMu.Unlock()
33+
service := globalSrv.Swap(nil)
3134
if service != nil {
3235
service.Stop()
3336
}
37+
if server == "" {
38+
return
39+
}
3440
ctx, cancel := context.WithCancel(context.Background())
3541
service = &Service{
3642
server: M.ParseSocksaddr(server),
@@ -41,87 +47,76 @@ func ReCreateNTPService(server string, interval time.Duration, dialerProxy strin
4147
syncSystemTime: syncSystemTime,
4248
}
4349
service.Start()
50+
globalSrv.Store(service)
4451
}
4552

4653
func (srv *Service) Start() {
47-
srv.mu.Lock()
48-
defer srv.mu.Unlock()
4954
log.Infoln("NTP service start, sync system time is %t", srv.syncSystemTime)
50-
err := srv.update()
51-
if err != nil {
52-
log.Errorln("Initialize NTP time failed: %s", err)
53-
return
54-
}
55-
service.running = true
5655
go srv.loopUpdate()
5756
}
5857

5958
func (srv *Service) Stop() {
60-
srv.mu.Lock()
61-
defer srv.mu.Unlock()
62-
if service.running {
63-
srv.ticker.Stop()
64-
srv.cancel()
65-
service.running = false
66-
}
59+
srv.cancel()
6760
}
6861

69-
func (srv *Service) Running() bool {
62+
func (srv *Service) Offset() time.Duration {
7063
if srv == nil {
71-
return false
64+
return 0
7265
}
73-
srv.mu.Lock()
74-
defer srv.mu.Unlock()
75-
return srv.running
66+
if srv.ctx.Err() != nil {
67+
return time.Duration(srv.offset.Load())
68+
}
69+
return 0
7670
}
7771

7872
func (srv *Service) update() error {
7973
var response *ntp.Response
8074
var err error
8175
for i := 0; i < 3; i++ {
82-
if response, err = ntp.Exchange(context.Background(), srv.dialer, srv.server); err == nil {
83-
break
76+
response, err = ntp.Exchange(srv.ctx, srv.dialer, srv.server)
77+
if err != nil {
78+
continue
8479
}
85-
if i == 2 {
86-
return err
80+
offset := response.ClockOffset
81+
if offset > time.Duration(0) {
82+
log.Infoln("System clock is ahead of NTP time by %s", offset)
83+
} else if offset < time.Duration(0) {
84+
log.Infoln("System clock is behind NTP time by %s", -offset)
8785
}
88-
}
89-
offset = response.ClockOffset
90-
if offset > time.Duration(0) {
91-
log.Infoln("System clock is ahead of NTP time by %s", offset)
92-
} else if offset < time.Duration(0) {
93-
log.Infoln("System clock is behind NTP time by %s", -offset)
94-
}
95-
if srv.syncSystemTime {
96-
timeNow := response.Time
97-
syncErr := setSystemTime(timeNow)
98-
if syncErr == nil {
99-
log.Infoln("Sync system time success: %s", timeNow.Local().Format(ntp.TimeLayout))
100-
} else {
101-
log.Errorln("Write time to system: %s", syncErr)
102-
srv.syncSystemTime = false
86+
srv.offset.Store(int64(offset))
87+
if srv.syncSystemTime {
88+
timeNow := response.Time
89+
syncErr := setSystemTime(timeNow)
90+
if syncErr == nil {
91+
log.Infoln("Sync system time success: %s", timeNow.Local().Format(ntp.TimeLayout))
92+
} else {
93+
log.Errorln("Write time to system: %s", syncErr)
94+
srv.syncSystemTime = false
95+
}
10396
}
97+
return nil
10498
}
105-
return nil
99+
return err
106100
}
107101

108102
func (srv *Service) loopUpdate() {
103+
defer srv.ticker.Stop()
109104
for {
105+
err := srv.update()
106+
if err != nil {
107+
log.Warnln("Sync time failed: %s", err)
108+
}
110109
select {
111110
case <-srv.ctx.Done():
112111
return
113112
case <-srv.ticker.C:
114113
}
115-
err := srv.update()
116-
if err != nil {
117-
log.Warnln("Sync time failed: %s", err)
118-
}
119114
}
120115
}
121116

122117
func Now() time.Time {
123118
now := time.Now()
124-
if service.Running() && offset.Abs() > 0 {
119+
if offset := globalSrv.Load().Offset(); offset.Abs() > 0 {
125120
now = now.Add(offset)
126121
}
127122
return now

0 commit comments

Comments
 (0)