diff --git a/go/racy-append-to-slice.go b/go/racy-append-to-slice.go index 13501e0..6e5ff2b 100644 --- a/go/racy-append-to-slice.go +++ b/go/racy-append-to-slice.go @@ -23,6 +23,9 @@ func main() { res6 := appendToSlice_FP4() printResults(res6) + + res7 := appendToSlice_FP5() + printResults(res7) } func appendToSlice1() []int { @@ -146,6 +149,28 @@ func appendToSlice_FP4() []int { return r } +func appendToSlice_FP5() []int { + // FP: The `append` is done inside a defer lock + var wg sync.WaitGroup + var rMut sync.Mutex + var r []int + for i := 0; i < 10; i++ { + wg.Add(1) + go func(iCpy int) { + defer wg.Done() + m := iCpy * 2 + // ok: racy-append-to-slice + rMut.Lock() + defer rMut.Unlock() + r = append(r, m) + }(i) + } + + wg.Wait() + + return r +} + func printResults(results []int) { for v, _ := range results { fmt.Println(v) diff --git a/go/racy-append-to-slice.yaml b/go/racy-append-to-slice.yaml index 8bbaaef..72a17a5 100644 --- a/go/racy-append-to-slice.yaml +++ b/go/racy-append-to-slice.yaml @@ -48,3 +48,7 @@ rules: $MUTEX.Lock() ... $MUTEX.Unlock() + - pattern-not-inside: | + $MUTEX.Lock() + defer $MUTEX.Unlock() + ... diff --git a/go/racy-write-to-map.go b/go/racy-write-to-map.go index bc2f4da..6cea44e 100644 --- a/go/racy-write-to-map.go +++ b/go/racy-write-to-map.go @@ -39,6 +39,10 @@ func main() { fmt.Println("appendToMap_FP4:") res6 := appendToMap_FP4() printMap(res6) + + fmt.Println("appendToMap_FP5:") + res7 := appendToMap_FP5() + printMap(res7) } func appendToMap1() map[int]string { @@ -160,6 +164,28 @@ func appendToMap_FP4() map[int]string { return r } +func appendToMap_FP5() map[int]string { + // FP: The map write is done inside a defer lock + var wg sync.WaitGroup + r := make(map[int]string) + var rMut sync.Mutex + + for i := 0; i < 10; i++ { + wg.Add(1) + go func(iCpy int) { + defer wg.Done() + // ok: racy-write-to-map + rMut.Lock() + defer rMut.Unlock() + r[iCpy] = fmt.Sprintf("number-%d", iCpy) + }(i) + } + + wg.Wait() + + return r +} + func printMap(results map[int]string) { for k, v := range results { fmt.Printf("key: %d, val: %s\n", k, v) diff --git a/go/racy-write-to-map.yaml b/go/racy-write-to-map.yaml index 4db1710..b978998 100644 --- a/go/racy-write-to-map.yaml +++ b/go/racy-write-to-map.yaml @@ -35,3 +35,7 @@ rules: $MUTEX.Lock() ... $MUTEX.Unlock() + - pattern-not-inside: | + $MUTEX.Lock() + defer $MUTEX.Unlock() + ...