@@ -22,6 +22,7 @@ import (
22
22
"context"
23
23
"fmt"
24
24
"sync"
25
+ "sync/atomic"
25
26
)
26
27
27
28
// provStore is the global singleton certificate provider store.
@@ -67,8 +68,7 @@ func (c closedProvider) Close() {
67
68
// singleCloseWrappedProvider wraps a provider instance with a reference count
68
69
// to properly handle multiple calls to Close.
69
70
type singleCloseWrappedProvider struct {
70
- mu sync.RWMutex
71
- provider Provider
71
+ provider atomic.Pointer [Provider ]
72
72
}
73
73
74
74
// store is a collection of provider instances, safe for concurrent access.
@@ -96,20 +96,21 @@ func (wp *wrappedProvider) Close() {
96
96
// Close overrides the Close method of the embedded provider to avoid release the
97
97
// already released reference.
98
98
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 ()
104
102
}
105
103
106
104
// KeyMaterial returns the key material sourced by the Provider.
107
105
// Callers are expected to use the returned value as read-only.
108
106
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
+ }
111
109
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
113
114
}
114
115
115
116
// BuildableConfig wraps parsed provider configuration and functionality to
@@ -149,7 +150,7 @@ func (bc *BuildableConfig) Build(opts BuildOptions) (Provider, error) {
149
150
}
150
151
if wp , ok := provStore .providers [sk ]; ok {
151
152
wp .refCount ++
152
- return & singleCloseWrappedProvider {provider : wp } , nil
153
+ return ( & singleCloseWrappedProvider {}). withProvider ( wp ) , nil
153
154
}
154
155
155
156
provider := bc .starter (opts )
@@ -163,7 +164,7 @@ func (bc *BuildableConfig) Build(opts BuildOptions) (Provider, error) {
163
164
store : provStore ,
164
165
}
165
166
provStore .providers [sk ] = wp
166
- return & singleCloseWrappedProvider {provider : wp } , nil
167
+ return ( & singleCloseWrappedProvider {}). withProvider ( wp ) , nil
167
168
}
168
169
169
170
// String returns the provider name and config as a colon separated string.
0 commit comments