Bladeren bron

Merge pull request #246 from sykesm/racing-stop

Replace lock with CAS in standard meter stop
Mikhail P 7 jaren geleden
bovenliggende
commit
3113b8401b
2 gewijzigde bestanden met toevoegingen van 6 en 7 verwijderingen
  1. 1 7
      meter.go
  2. 5 0
      meter_test.go

+ 1 - 7
meter.go

@@ -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
@@ -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()

+ 5 - 0
meter_test.go

@@ -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()
 }