Fix race in miner

License: MIT
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
This commit is contained in:
Jakub Sztandera 2019-11-19 17:21:54 -06:00
parent 463cdbb499
commit fe8a700a4f
No known key found for this signature in database
GPG Key ID: 9A9AF56F8B3879BA

View File

@ -82,7 +82,6 @@ func (m *Miner) Register(addr address.Address) error {
m.addresses = append(m.addresses, addr) m.addresses = append(m.addresses, addr)
if len(m.addresses) == 1 { if len(m.addresses) == 1 {
// TODO: there is probably a race here
m.stop = make(chan struct{}) m.stop = make(chan struct{})
go m.mine(context.TODO()) go m.mine(context.TODO())
} }
@ -92,8 +91,8 @@ func (m *Miner) Register(addr address.Address) error {
func (m *Miner) Unregister(ctx context.Context, addr address.Address) error { func (m *Miner) Unregister(ctx context.Context, addr address.Address) error {
m.lk.Lock() m.lk.Lock()
defer m.lk.Unlock()
if len(m.addresses) == 0 { if len(m.addresses) == 0 {
m.lk.Unlock()
return xerrors.New("no addresses registered") return xerrors.New("no addresses registered")
} }
@ -106,7 +105,6 @@ func (m *Miner) Unregister(ctx context.Context, addr address.Address) error {
} }
} }
if idx == -1 { if idx == -1 {
m.lk.Unlock()
return xerrors.New("unregister: address not found") return xerrors.New("unregister: address not found")
} }
@ -115,21 +113,17 @@ func (m *Miner) Unregister(ctx context.Context, addr address.Address) error {
// Unregistering last address, stop mining first // Unregistering last address, stop mining first
if len(m.addresses) == 0 && m.stop != nil { if len(m.addresses) == 0 && m.stop != nil {
if m.stopping == nil {
m.stopping = make(chan struct{}) m.stopping = make(chan struct{})
close(m.stop)
}
stopping := m.stopping stopping := m.stopping
m.lk.Unlock() close(m.stop)
select { select {
case <-stopping: case <-stopping:
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return ctx.Err()
} }
m.lk.Lock()
} }
m.lk.Unlock()
return nil return nil
} }
@ -143,15 +137,12 @@ eventLoop:
for { for {
select { select {
case <-m.stop: case <-m.stop:
m.lk.Lock() stopping := m.stopping
close(m.stopping)
m.stop = nil m.stop = nil
m.stopping = nil m.stopping = nil
close(stopping)
m.lk.Unlock()
return return
default: default:
} }