diff --git a/debounce.go b/debounce.go index 6d26069..793d5ed 100644 --- a/debounce.go +++ b/debounce.go @@ -1,4 +1,4 @@ -// Copyright © 2016 Bjørn Erik Pedersen . +// Copyright © 2019 Bjørn Erik Pedersen . // // Use of this source code is governed by an MIT-style // license that can be found in the LICENSE file. @@ -9,6 +9,7 @@ package debounce import ( + "sync" "time" ) @@ -26,11 +27,15 @@ func New(after time.Duration) func(f func()) { } type debouncer struct { + mu sync.Mutex after time.Duration timer *time.Timer } func (d *debouncer) add(f func()) { + d.mu.Lock() + defer d.mu.Unlock() + if d.timer != nil { d.timer.Stop() } diff --git a/debounce_test.go b/debounce_test.go index a9dc6fc..16f864d 100644 --- a/debounce_test.go +++ b/debounce_test.go @@ -2,6 +2,7 @@ package debounce_test import ( "fmt" + "sync" "sync/atomic" "testing" "time" @@ -58,6 +59,31 @@ func TestDebounce(t *testing.T) { } } +func TestDebounceConcurrentAdd(t *testing.T) { + var wg sync.WaitGroup + + var flag uint64 + + debounced := debounce.New(100 * time.Millisecond) + + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + defer wg.Done() + debounced(func() { + atomic.CompareAndSwapUint64(&flag, 0, 1) + }) + }() + } + wg.Wait() + + time.Sleep(500 * time.Millisecond) + c := int(atomic.LoadUint64(&flag)) + if c != 1 { + t.Error("Flag not set") + } +} + // Issue #1 func TestDebounceDelayed(t *testing.T) { @@ -75,7 +101,7 @@ func TestDebounceDelayed(t *testing.T) { debounced(f1) - time.Sleep(110 * time.Millisecond) + time.Sleep(200 * time.Millisecond) c1 := int(atomic.LoadUint64(&counter1)) if c1 != 1 {