@@ -47,6 +47,7 @@ import kotlinx.coroutines.ensureActive
47
47
import kotlinx.coroutines.flow.MutableStateFlow
48
48
import kotlinx.coroutines.flow.filter
49
49
import kotlinx.coroutines.flow.first
50
+ import kotlinx.coroutines.flow.getAndUpdate
50
51
import kotlinx.coroutines.launch
51
52
52
53
/* * Base class that shares logic for managing the Auth token and AppCheck token. */
@@ -148,9 +149,18 @@ internal sealed class DataConnectCredentialsTokenManager<T : Any>(
148
149
*/
149
150
fun close () {
150
151
logger.debug { " close()" }
152
+
151
153
weakThis.clear()
152
154
coroutineScope.cancel()
153
- setClosedState()
155
+
156
+ val oldState = state.getAndUpdate { State .Closed }
157
+ when (oldState) {
158
+ is State .Closed -> {}
159
+ is State .New -> {}
160
+ is State .StateWithProvider -> {
161
+ removeTokenListener(oldState.provider)
162
+ }
163
+ }
154
164
}
155
165
156
166
/* *
@@ -175,51 +185,30 @@ internal sealed class DataConnectCredentialsTokenManager<T : Any>(
175
185
logger.debug { " awaitTokenProvider() done: currentState=$currentState " }
176
186
}
177
187
178
- // This function must ONLY be called from close().
179
- private fun setClosedState () {
180
- while (true ) {
181
- val oldState = state.value
182
- val provider: T ? =
183
- when (oldState) {
184
- is State .Closed -> return
185
- is State .New -> null
186
- is State .Idle -> oldState.provider
187
- is State .Active -> oldState.provider
188
- }
189
-
190
- if (state.compareAndSet(oldState, State .Closed )) {
191
- provider?.let { removeTokenListener(it) }
192
- break
193
- }
194
- }
195
- }
196
-
197
188
/* *
198
189
* Sets a flag to force-refresh the token upon the next call to [getToken].
199
190
*
200
191
* If [close] has been called, this method does nothing.
201
192
*/
202
193
fun forceRefresh () {
203
194
logger.debug { " forceRefresh()" }
204
- while (true ) {
205
- val oldState = state.value
206
- val newState: State .StateWithForceTokenRefresh <T > =
195
+ val oldState =
196
+ state.getAndUpdate { oldState ->
207
197
when (oldState) {
208
- is State .Closed -> return
198
+ is State .Closed -> State . Closed
209
199
is State .New -> oldState.copy(forceTokenRefresh = true )
210
200
is State .Idle -> oldState.copy(forceTokenRefresh = true )
211
- is State .Active -> {
212
- val message = " needs token refresh (wgrwbrvjxt)"
213
- oldState.job.cancel(message, ForceRefresh (message))
214
- State .Idle (oldState.provider, forceTokenRefresh = true )
215
- }
201
+ is State .Active -> State .Idle (oldState.provider, forceTokenRefresh = true )
216
202
}
217
-
218
- check(newState.forceTokenRefresh) {
219
- " newState.forceTokenRefresh should be true (error code gnvr2wx7nz)"
220
203
}
221
- if (state.compareAndSet(oldState, newState)) {
222
- break
204
+
205
+ when (oldState) {
206
+ is State .Closed -> {}
207
+ is State .New -> {}
208
+ is State .Idle -> {}
209
+ is State .Active -> {
210
+ val message = " needs token refresh (wgrwbrvjxt)"
211
+ oldState.job.cancel(message, ForceRefresh (message))
223
212
}
224
213
}
225
214
}
@@ -350,30 +339,30 @@ internal sealed class DataConnectCredentialsTokenManager<T : Any>(
350
339
logger.debug { " onProviderAvailable(newProvider=$newProvider )" }
351
340
addTokenListener(newProvider)
352
341
353
- while (true ) {
354
- val oldState = state.value
355
- val newState =
342
+ val oldState =
343
+ state.getAndUpdate { oldState ->
356
344
when (oldState) {
357
- is State .Closed -> {
358
- logger.debug {
359
- " onProviderAvailable(newProvider=$newProvider )" +
360
- " unregistering token listener that was just added"
361
- }
362
- removeTokenListener(newProvider)
363
- break
364
- }
345
+ is State .Closed -> State .Closed
365
346
is State .New -> State .Idle (newProvider, oldState.forceTokenRefresh)
366
347
is State .Idle -> State .Idle (newProvider, oldState.forceTokenRefresh)
367
- is State .Active -> {
368
- val newProviderClassName = newProvider::class .qualifiedName
369
- val message = " a new provider $newProviderClassName is available (symhxtmazy)"
370
- oldState.job.cancel(message, NewProvider (message))
371
- State .Idle (newProvider, forceTokenRefresh = false )
372
- }
348
+ is State .Active -> State .Idle (newProvider, forceTokenRefresh = false )
373
349
}
350
+ }
374
351
375
- if (state.compareAndSet(oldState, newState)) {
376
- break
352
+ when (oldState) {
353
+ is State .Closed -> {
354
+ logger.debug {
355
+ " onProviderAvailable(newProvider=$newProvider )" +
356
+ " unregistering token listener that was just added"
357
+ }
358
+ removeTokenListener(newProvider)
359
+ }
360
+ is State .New -> {}
361
+ is State .Idle -> {}
362
+ is State .Active -> {
363
+ val newProviderClassName = newProvider::class .qualifiedName
364
+ val message = " a new provider $newProviderClassName is available (symhxtmazy)"
365
+ oldState.job.cancel(message, NewProvider (message))
377
366
}
378
367
}
379
368
}
0 commit comments