Skip to content

Commit 527266f

Browse files
committed
fixup! Fix close in use certificate providers after double Close() method call on wrapper object
1 parent 5c3ab05 commit 527266f

File tree

1 file changed

+13
-12
lines changed

1 file changed

+13
-12
lines changed

credentials/tls/certprovider/store.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"context"
2323
"fmt"
2424
"sync"
25+
"sync/atomic"
2526
)
2627

2728
// provStore is the global singleton certificate provider store.
@@ -67,8 +68,7 @@ func (c closedProvider) Close() {
6768
// singleCloseWrappedProvider wraps a provider instance with a reference count
6869
// to properly handle multiple calls to Close.
6970
type singleCloseWrappedProvider struct {
70-
mu sync.RWMutex
71-
provider Provider
71+
provider atomic.Pointer[Provider]
7272
}
7373

7474
// store is a collection of provider instances, safe for concurrent access.
@@ -96,20 +96,21 @@ func (wp *wrappedProvider) Close() {
9696
// Close overrides the Close method of the embedded provider to avoid release the
9797
// already released reference.
9898
func (w *singleCloseWrappedProvider) Close() {
99-
w.mu.Lock()
100-
defer w.mu.Unlock()
101-
102-
w.provider.Close()
103-
w.provider = closedProvider{}
99+
newProvider := Provider(closedProvider{})
100+
oldProvider := w.provider.Swap(&newProvider)
101+
(*oldProvider).Close()
104102
}
105103

106104
// KeyMaterial returns the key material sourced by the Provider.
107105
// Callers are expected to use the returned value as read-only.
108106
func (w *singleCloseWrappedProvider) KeyMaterial(ctx context.Context) (*KeyMaterial, error) {
109-
w.mu.RLock()
110-
defer w.mu.RUnlock()
107+
return (*w.provider.Load()).KeyMaterial(ctx)
108+
}
111109

112-
return w.provider.KeyMaterial(ctx)
110+
// withProvider set provider to wrapper.
111+
func (w *singleCloseWrappedProvider) withProvider(provider Provider) *singleCloseWrappedProvider {
112+
w.provider.Store(&provider)
113+
return w
113114
}
114115

115116
// BuildableConfig wraps parsed provider configuration and functionality to
@@ -149,7 +150,7 @@ func (bc *BuildableConfig) Build(opts BuildOptions) (Provider, error) {
149150
}
150151
if wp, ok := provStore.providers[sk]; ok {
151152
wp.refCount++
152-
return &singleCloseWrappedProvider{provider: wp}, nil
153+
return (&singleCloseWrappedProvider{}).withProvider(wp), nil
153154
}
154155

155156
provider := bc.starter(opts)
@@ -163,7 +164,7 @@ func (bc *BuildableConfig) Build(opts BuildOptions) (Provider, error) {
163164
store: provStore,
164165
}
165166
provStore.providers[sk] = wp
166-
return &singleCloseWrappedProvider{provider: wp}, nil
167+
return (&singleCloseWrappedProvider{}).withProvider(wp), nil
167168
}
168169

169170
// String returns the provider name and config as a colon separated string.

0 commit comments

Comments
 (0)