]> Cypherpunks repositories - gostls13.git/commitdiff
time: fix timer stop
authorDmitriy Vyukov <dvyukov@google.com>
Fri, 25 Nov 2011 11:13:10 +0000 (14:13 +0300)
committerDmitriy Vyukov <dvyukov@google.com>
Fri, 25 Nov 2011 11:13:10 +0000 (14:13 +0300)
Due to data structure corruption,
some timers could not be removed.
Fixes #2495.

R=golang-dev, adg
CC=golang-dev, mdbrown
https://golang.org/cl/5437060

src/pkg/runtime/time.goc
src/pkg/time/sleep_test.go

index 23ad1aaef7ecb41c0d96cc71b88d9b82d1b62ac7..ad9f3aac564055c594fb408b2fff8eeae5380953 100644 (file)
@@ -133,9 +133,16 @@ deltimer(Timer *t)
                return false;
        }
 
-       timers.t[i] = timers.t[--timers.len];
-       siftup(i);
-       siftdown(i);
+       timers.len--;
+       if(i == timers.len) {
+               timers.t[i] = nil;
+       } else {
+               timers.t[i] = timers.t[timers.len];
+               timers.t[timers.len] = nil;
+               timers.t[i]->i = i;
+               siftup(i);
+               siftdown(i);
+       }
        runtimeĀ·unlock(&timers);
        return true;
 }
index 4c4a079880a2ee16fa21eb11433b1f72d3e6165b..6fa2b69c509eb767a045f277b7eda593c9101662 100644 (file)
@@ -205,3 +205,19 @@ func testAfterQueuing(t *testing.T) error {
        }
        return nil
 }
+
+func TestTimerStopStress(t *testing.T) {
+       if testing.Short() {
+               return
+       }
+       for i := 0; i < 100; i++ {
+               go func(i int) {
+                       timer := AfterFunc(2e9, func() {
+                               t.Fatalf("timer %d was not stopped", i)
+                       })
+                       Sleep(1e9)
+                       timer.Stop()
+               }(i)
+       }
+       Sleep(3e9)
+}