Skip to content

Commit

Permalink
Replace lock with CAS in standard meter stop
Browse files Browse the repository at this point in the history
Fixes rcrowley#245

Signed-off-by: Matthew Sykes <[email protected]>
  • Loading branch information
sykesm committed Oct 1, 2018
1 parent e2704e1 commit 5195ae7
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 7 deletions.
8 changes: 1 addition & 7 deletions meter.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,6 @@ func (NilMeter) Stop() {}

// StandardMeter is the standard implementation of a Meter.
type StandardMeter struct {
// Only used on stop.
lock sync.Mutex
snapshot *MeterSnapshot
a1, a5, a15 EWMA
startTime time.Time
Expand All @@ -146,11 +144,7 @@ func newStandardMeter() *StandardMeter {

// Stop stops the meter, Mark() will be a no-op if you use it after being stopped.
func (m *StandardMeter) Stop() {
m.lock.Lock()
stopped := m.stopped
m.stopped = 1
m.lock.Unlock()
if stopped != 1 {
if atomic.CompareAndSwapUint32(&m.stopped, 0, 1) {
arbiter.Lock()
delete(arbiter.meters, m)
arbiter.Unlock()
Expand Down
5 changes: 5 additions & 0 deletions meter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ func TestMeterConcurrency(t *testing.T) {
m.Mark(1)
wg.Done()
}(m, wg)
wg.Add(1)
go func(m Meter, wg *sync.WaitGroup) {
m.Stop()
wg.Done()
}(m, wg)
}
wg.Wait()
}
Expand Down

0 comments on commit 5195ae7

Please sign in to comment.