Skip to content

Commit fd7af42

Browse files
committed
fixup! Fix close in use certificate providers after double Close() method call on wrapper object
1 parent 3bf8e1f commit fd7af42

File tree

1 file changed

+24
-19
lines changed

1 file changed

+24
-19
lines changed

credentials/tls/certprovider/store.go

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ type storeKey struct {
4545

4646
// wrappedProvider wraps a provider instance with a reference count.
4747
type wrappedProvider struct {
48-
provider Provider
48+
Provider
4949
refCount int
5050

5151
// A reference to the key and store are also kept here to override the
@@ -54,11 +54,21 @@ type wrappedProvider struct {
5454
store *store
5555
}
5656

57-
// wrappedProviderCloser wraps a provider instance with a reference count to avoid double
57+
// closedProvider always returns errProviderClosed error.
58+
type closedProvider struct{}
59+
60+
func (c closedProvider) KeyMaterial(ctx context.Context) (*KeyMaterial, error) {
61+
return nil, errProviderClosed
62+
}
63+
64+
func (c closedProvider) Close() {
65+
}
66+
67+
// singleCloseWrappedProvider wraps a provider instance with a reference count to avoid double
5868
// close still in use provider.
59-
type wrappedProviderCloser struct {
60-
mu sync.RWMutex
61-
wp *wrappedProvider
69+
type singleCloseWrappedProvider struct {
70+
mu sync.RWMutex
71+
provider Provider
6272
}
6373

6474
// store is a collection of provider instances, safe for concurrent access.
@@ -78,32 +88,27 @@ func (wp *wrappedProvider) Close() {
7888

7989
wp.refCount--
8090
if wp.refCount == 0 {
81-
wp.provider.Close()
91+
wp.Provider.Close()
8292
delete(ps.providers, wp.storeKey)
8393
}
8494
}
8595

8696
// Close overrides the Close method of the embedded provider to avoid release the
8797
// already released reference.
88-
func (w *wrappedProviderCloser) Close() {
98+
func (w *singleCloseWrappedProvider) Close() {
8999
w.mu.Lock()
90100
defer w.mu.Unlock()
91-
if wp := w.wp; wp != nil {
92-
w.wp = nil
93-
wp.Close()
94-
}
101+
w.provider.Close()
102+
w.provider = closedProvider{}
95103
}
96104

97105
// KeyMaterial returns the key material sourced by the Provider.
98106
// Callers are expected to use the returned value as read-only.
99-
func (w *wrappedProviderCloser) KeyMaterial(ctx context.Context) (*KeyMaterial, error) {
107+
func (w *singleCloseWrappedProvider) KeyMaterial(ctx context.Context) (*KeyMaterial, error) {
100108
w.mu.RLock()
101109
defer w.mu.RUnlock()
102110

103-
if w.wp == nil {
104-
return nil, errProviderClosed
105-
}
106-
return w.wp.provider.KeyMaterial(ctx)
111+
return w.provider.KeyMaterial(ctx)
107112
}
108113

109114
// BuildableConfig wraps parsed provider configuration and functionality to
@@ -143,21 +148,21 @@ func (bc *BuildableConfig) Build(opts BuildOptions) (Provider, error) {
143148
}
144149
if wp, ok := provStore.providers[sk]; ok {
145150
wp.refCount++
146-
return &wrappedProviderCloser{wp: wp}, nil
151+
return &singleCloseWrappedProvider{provider: wp}, nil
147152
}
148153

149154
provider := bc.starter(opts)
150155
if provider == nil {
151156
return nil, fmt.Errorf("provider(%q, %q).Build(%v) failed", sk.name, sk.config, opts)
152157
}
153158
wp := &wrappedProvider{
154-
provider: provider,
159+
Provider: provider,
155160
refCount: 1,
156161
storeKey: sk,
157162
store: provStore,
158163
}
159164
provStore.providers[sk] = wp
160-
return &wrappedProviderCloser{wp: wp}, nil
165+
return &singleCloseWrappedProvider{provider: wp}, nil
161166
}
162167

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

0 commit comments

Comments
 (0)