Skip to content

fix: defer mutex unlock to avoid locked after panic

Florent Peterschmitt requested to merge fix-deadlock into develop

canopsis/canopsis#814

Cas simple d’utilisation du defer lors d’un panic :

package main

import (
	"fmt"
	"sync"
)

type tt struct {
	l sync.RWMutex
}

func (t *tt) Panic(c bool) {
	if c {
		panic("we're all dead")
	}
}

func (t *tt) LastWords() {
	t.l.Unlock()
	fmt.Println("will be ok")
}

func (t *tt) Work(c bool) {
	t.l.Lock()
	defer t.LastWords()
	t.Panic(c)
}

func main() {
	t := tt{}
	t.Work(true)
}

On verra quelque chose du genre :

will be ok
panic: we're all dead

goroutine 1 [running]:
main.(*tt).Panic(0xc420012340, 0x4b9101)
        /home/florent/doc/go/src/Leryan/gorun/main.go:14 +0x4c
main.(*tt).Work(0xc420012340, 0xc420012301)
        /home/florent/doc/go/src/Leryan/gorun/main.go:26 +0x6a
main.main()
        /home/florent/doc/go/src/Leryan/gorun/main.go:31 +0x40

La fonction LastWords() a bien été appelée avant que le panic ne se propage, du coup il n’y a pas de raison pour que le mutex reste vérouillé.

L’utilisation de defer est donc à généraliser lorsqu’on utilise un mutex.

@dwatteau @tgosselin @adewarumez @rhennuyer

Edited by Florent Peterschmitt

Merge request reports