From ad9fcae3ad37c29aff1f84045f29ed2536d9f167 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 2 Jun 2026 12:19:20 -0700 Subject: [PATCH] Handle java.util.ConcurrentModificationException while unregistering sensor listeners We're still seeing this frequently when unregistering PlayStation controller sensors. We don't know what else is modifying the sensor list, but if we end up getting this exception we'll retry after a short sleep. (cherry picked from commit 75270a426484ab8d3d2c9559745a09e6658f668a) --- .../java/org/libsdl/app/SDLSensorManager.java | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLSensorManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLSensorManager.java index 586e3fab6e..4ed4f01278 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLSensorManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLSensorManager.java @@ -3,6 +3,7 @@ package org.libsdl.app; import android.hardware.Sensor; import android.hardware.SensorEventListener; import android.hardware.SensorManager; +import android.util.Log; // This class coordinates synchronized access to sensor manager registration // @@ -13,6 +14,8 @@ class SDLSensorManager { static private SDLSensorManager mManager = new SDLSensorManager(); + static final int RETRY_COUNT = 3; + public static void registerListener(SensorManager manager, SensorEventListener listener, Sensor sensor, int samplingPeriodUs) { mManager.RegisterListener(manager, listener, sensor, samplingPeriodUs); } @@ -22,11 +25,49 @@ class SDLSensorManager } private synchronized void RegisterListener(SensorManager manager, SensorEventListener listener, Sensor sensor, int samplingPeriodUs) { - manager.registerListener(listener, sensor, samplingPeriodUs, null); + int retries = 0; + boolean complete = false; + while (!complete) { + try { + manager.registerListener(listener, sensor, samplingPeriodUs, null); + complete = true; + } catch (java.util.ConcurrentModificationException e) { + ++retries; + if (retries <= RETRY_COUNT) { + // Sleep a bit and try again + try { + Thread.sleep(1); + } catch (Exception e2) { + } + } else { + Log.v("SDL", "Multiple ConcurrentModificationException caught while registering sensor listener, canceling operation"); + complete = true; + } + } + } } private synchronized void UnregisterListener(SensorManager manager, SensorEventListener listener, Sensor sensor) { - manager.unregisterListener(listener, sensor); + int retries = 0; + boolean complete = false; + while (!complete) { + try { + manager.unregisterListener(listener, sensor); + complete = true; + } catch (java.util.ConcurrentModificationException e) { + ++retries; + if (retries <= RETRY_COUNT) { + // Sleep a bit and try again + try { + Thread.sleep(1); + } catch (Exception e2) { + } + } else { + Log.v("SDL", "Multiple ConcurrentModificationException caught while unregistering sensor listener, canceling operation"); + complete = true; + } + } + } } }