File tree Expand file tree Collapse file tree 2 files changed +41
-1
lines changed
compose/runtime/runtime/src
commonMain/kotlin/androidx/compose/runtime/snapshots
test/kotlin/androidx/compose/runtime/snapshots Expand file tree Collapse file tree 2 files changed +41
-1
lines changed Original file line number Diff line number Diff line change @@ -53,7 +53,9 @@ class SnapshotStateObserver(private val onChangedExecutor: (callback: () -> Unit
53
53
*/
54
54
private val readObserver: (Any ) -> Unit = { state ->
55
55
if (! isPaused) {
56
- currentMap!! .addValue(state)
56
+ synchronized(applyMaps) {
57
+ currentMap!! .addValue(state)
58
+ }
57
59
}
58
60
}
59
61
Original file line number Diff line number Diff line change @@ -324,6 +324,44 @@ class SnapshotStateObserverTests {
324
324
assertNull(threadException)
325
325
}
326
326
327
+ @Test // regression test for 192677711, second case
328
+ fun tryToReproduceSecondRaceCondtion () {
329
+ var running = true
330
+ var threadException: Exception ? = null
331
+ try {
332
+ thread {
333
+ try {
334
+ while (running) {
335
+ Snapshot .sendApplyNotifications()
336
+ }
337
+ } catch (e: Exception ) {
338
+ threadException = e
339
+ }
340
+ }
341
+
342
+ for (i in 1 .. 10000 ) {
343
+ val state1 by mutableStateOf(0 )
344
+ var state2 by mutableStateOf(true )
345
+ val observer = SnapshotStateObserver ({}).apply {
346
+ start()
347
+ }
348
+ observer.observeReads(Unit , {}) {
349
+ repeat(1000 ) {
350
+ @Suppress(" UNUSED_EXPRESSION" )
351
+ state1
352
+ if (state2) {
353
+ state2 = false
354
+ }
355
+ }
356
+ }
357
+ assertNull(threadException)
358
+ }
359
+ } finally {
360
+ running = false
361
+ }
362
+ assertNull(threadException)
363
+ }
364
+
327
365
private fun runSimpleTest (
328
366
block : (modelObserver: SnapshotStateObserver , data: MutableState <Int >) -> Unit
329
367
) {
You can’t perform that action at this time.
0 commit comments