Skip to content

Commit b750cab

Browse files
committed
miner: fix a race between remote agent start/loop
1 parent a98e8c0 commit b750cab

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

miner/remote_agent.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type hashrate struct {
3737
type RemoteAgent struct {
3838
mu sync.Mutex
3939

40-
quit chan struct{}
40+
quitCh chan struct{}
4141
workCh chan *Work
4242
returnCh chan<- *Result
4343

@@ -76,18 +76,16 @@ func (a *RemoteAgent) Start() {
7676
if !atomic.CompareAndSwapInt32(&a.running, 0, 1) {
7777
return
7878
}
79-
80-
a.quit = make(chan struct{})
79+
a.quitCh = make(chan struct{})
8180
a.workCh = make(chan *Work, 1)
82-
go a.maintainLoop()
81+
go a.loop(a.workCh, a.quitCh)
8382
}
8483

8584
func (a *RemoteAgent) Stop() {
8685
if !atomic.CompareAndSwapInt32(&a.running, 1, 0) {
8786
return
8887
}
89-
90-
close(a.quit)
88+
close(a.quitCh)
9189
close(a.workCh)
9290
}
9391

@@ -148,15 +146,20 @@ func (a *RemoteAgent) SubmitWork(nonce uint64, mixDigest, hash common.Hash) bool
148146
return false
149147
}
150148

151-
func (a *RemoteAgent) maintainLoop() {
149+
// loop monitors mining events on the work and quit channels, updating the internal
150+
// state of the rmeote miner until a termination is requested.
151+
//
152+
// Note, the reason the work and quit channels are passed as parameters is because
153+
// RemoteAgent.Start() constantly recreates these channels, so the loop code cannot
154+
// assume data stability in these member fields.
155+
func (a *RemoteAgent) loop(workCh chan *Work, quitCh chan struct{}) {
152156
ticker := time.Tick(5 * time.Second)
153157

154-
out:
155158
for {
156159
select {
157-
case <-a.quit:
158-
break out
159-
case work := <-a.workCh:
160+
case <-quitCh:
161+
return
162+
case work := <-workCh:
160163
a.mu.Lock()
161164
a.currentWork = work
162165
a.mu.Unlock()

0 commit comments

Comments
 (0)