@@ -51,8 +51,9 @@ type installer struct {
5151 // deferredBackends tracks backends whose installation is deferred until
5252 // explicitly requested via installBackend.
5353 deferredBackends map [string ]bool
54- // mu protects on-demand installation via installBackend.
55- mu sync.Mutex
54+ // mu protects statuses map mutations in installBackend. Readers
55+ // (wait, isInstalled) take an RLock; installBackend takes a full Lock.
56+ mu sync.RWMutex
5657}
5758
5859// newInstaller creates a new backend installer. Backends listed in
@@ -155,8 +156,10 @@ func (i *installer) run(ctx context.Context) {
155156// For deferred backends that have never been installed, it returns
156157// errBackendNotInstalled immediately instead of blocking.
157158func (i * installer ) wait (ctx context.Context , backend string ) error {
158- // Grab the backend status.
159+ // Grab the backend status under a read lock, since installBackend may replace entries in the map.
160+ i .mu .RLock ()
159161 status , ok := i .statuses [backend ]
162+ i .mu .RUnlock ()
160163 if ! ok {
161164 return ErrBackendNotFound
162165 }
@@ -238,7 +241,9 @@ func (i *installer) installBackend(ctx context.Context, name string) error {
238241// isInstalled returns true if the given backend has completed installation.
239242// It is non-blocking.
240243func (i * installer ) isInstalled (name string ) bool {
244+ i .mu .RLock ()
241245 status , ok := i .statuses [name ]
246+ i .mu .RUnlock ()
242247 if ! ok {
243248 return false
244249 }
0 commit comments