1
0
mirror of https://github.com/golang/go synced 2024-11-18 15:24:41 -07:00

time: prevent a panic from leaving the timer mutex held

When deleting a timer, a panic due to nil deref
would leave a lock held, possibly leading to a deadlock
in a defer. Instead return false on a nil timer.

Fixes #5745.

R=golang-dev, daniel.morsing, dvyukov, rsc, iant
CC=golang-dev
https://golang.org/cl/10373047
This commit is contained in:
Jeff R. Allen 2013-07-01 21:42:29 -04:00 committed by Russ Cox
parent b86f6c9224
commit 0286b4738e
2 changed files with 25 additions and 0 deletions

View File

@ -131,6 +131,11 @@ runtime·deltimer(Timer *t)
{
int32 i;
// Dereference t so that any panic happens before the lock is held.
// Discard result, because t might be moving in the heap.
i = t->i;
USED(i);
runtime·lock(&timers);
// t may not be registered anymore and may have

View File

@ -314,3 +314,23 @@ func TestOverflowSleep(t *testing.T) {
t.Fatalf("negative timeout didn't fire")
}
}
// Test that a panic while deleting a timer does not leave
// the timers mutex held, deadlocking a ticker.Stop in a defer.
func TestIssue5745(t *testing.T) {
ticker := NewTicker(Hour)
defer func() {
// would deadlock here before the fix due to
// lock taken before the segfault.
ticker.Stop()
if r := recover(); r == nil {
t.Error("Expected panic, but none happened.")
}
}()
// cause a panic due to a segfault
var timer *Timer
timer.Stop()
t.Error("Should be unreachable.")
}