syncs: add Map.WithLock to allow mutations to the underlying map (#8101)

Some operations cannot be implemented with the prior API:
* Iterating over the map and deleting keys
* Iterating over the map and replacing items
* Calling APIs that expect a native Go map

Add a Map.WithLock method that acquires a write-lock on the map
and then calls a user-provided closure with the underlying Go map.
This allows users to interact with the Map as a regular Go map,
but with the gaurantees that it is concurrent safe.

Updates tailscale/corp#9115

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This commit is contained in:
Joe Tsai
2024-07-11 16:16:30 -07:00
committed by GitHub
parent fc28c8e7f3
commit d209b032ab
2 changed files with 15 additions and 13 deletions

View File

@@ -7,7 +7,6 @@ import (
"context"
"io"
"os"
"sync"
"testing"
"github.com/google/go-cmp/cmp"
@@ -189,19 +188,11 @@ func TestMap(t *testing.T) {
t.Run("LoadOrStore", func(t *testing.T) {
var m Map[string, string]
var wg sync.WaitGroup
wg.Add(2)
var wg WaitGroup
var ok1, ok2 bool
go func() {
defer wg.Done()
_, ok1 = m.LoadOrStore("", "")
}()
go func() {
defer wg.Done()
_, ok2 = m.LoadOrStore("", "")
}()
wg.Go(func() { _, ok1 = m.LoadOrStore("", "") })
wg.Go(func() { _, ok2 = m.LoadOrStore("", "") })
wg.Wait()
if ok1 == ok2 {
t.Errorf("exactly one LoadOrStore should load")
}