Skip to content

Commit a1a2231

Browse files
romtsnclaude
andcommitted
fix(feedback): Synchronize SampleQueue access across threads
stop() runs on the main thread while onSensorChanged() runs on the background HandlerThread. Without synchronization, concurrent access to the linked list and object pool can corrupt next-pointers and cause clear() to loop forever. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f663782 commit a1a2231

1 file changed

Lines changed: 14 additions & 7 deletions

File tree

sentry-android-core/src/main/java/io/sentry/android/core/SentryShakeDetector.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,12 @@ public void start(final @NotNull Context context, final @NotNull Listener shakeL
9191

9292
public void stop() {
9393
listener = null;
94-
queue.clear();
9594
if (sensorManager != null) {
9695
sensorManager.unregisterListener(this);
9796
}
97+
synchronized (queue) {
98+
queue.clear();
99+
}
98100
}
99101

100102
/** Stops detection and releases the background thread. */
@@ -117,14 +119,19 @@ public void onSensorChanged(final @NotNull SensorEvent event) {
117119
final float az = event.values[2];
118120
final boolean accelerating = Math.sqrt(ax * ax + ay * ay + az * az) > ACCELERATION_THRESHOLD;
119121

120-
queue.add(event.timestamp, accelerating);
121-
if (queue.isShaking()) {
122-
queue.clear();
123-
final @Nullable Listener currentListener = listener;
124-
if (currentListener != null) {
125-
currentListener.onShake();
122+
final @Nullable Listener currentListener;
123+
synchronized (queue) {
124+
queue.add(event.timestamp, accelerating);
125+
if (queue.isShaking()) {
126+
queue.clear();
127+
currentListener = listener;
128+
} else {
129+
currentListener = null;
126130
}
127131
}
132+
if (currentListener != null) {
133+
currentListener.onShake();
134+
}
128135
}
129136

130137
@Override

0 commit comments

Comments
 (0)