@@ -30,7 +30,7 @@ import io.sentry.transport.ICurrentDateProvider
3030import io.sentry.util.FileUtils
3131import java.io.File
3232import java.util.Date
33- import java.util.concurrent.CopyOnWriteArrayList
33+ import java.util.LinkedList
3434import java.util.concurrent.Executors
3535import java.util.concurrent.ScheduledExecutorService
3636import java.util.concurrent.ThreadFactory
@@ -71,7 +71,8 @@ internal abstract class BaseCaptureStrategy(
7171 override val currentSegment = AtomicInteger (0 )
7272 override val replayCacheDir: File ? get() = cache?.replayCacheDir
7373
74- protected val currentEvents = CopyOnWriteArrayList <RRWebEvent >()
74+ protected val currentEvents = LinkedList <RRWebEvent >()
75+ private val currentEventsLock = Any ()
7576 private val currentPositions = mutableListOf<Position >()
7677 private var touchMoveBaseline = 0L
7778 private var lastCapturedMoveEvent = 0L
@@ -264,11 +265,11 @@ internal abstract class BaseCaptureStrategy(
264265 }
265266 }
266267 }
267- currentEvents.removeAll {
268- if (it.timestamp > segmentTimestamp.time && it.timestamp < endTimestamp.time) {
269- recordingPayload + = it
268+
269+ rotateCurrentEvents(endTimestamp.time) { event ->
270+ if (event.timestamp >= segmentTimestamp.time) {
271+ recordingPayload + = event
270272 }
271- it.timestamp < endTimestamp.time
272273 }
273274
274275 val recording = ReplayRecording ().apply {
@@ -290,14 +291,30 @@ internal abstract class BaseCaptureStrategy(
290291 override fun onTouchEvent (event : MotionEvent ) {
291292 val rrwebEvent = event.toRRWebIncrementalSnapshotEvent()
292293 if (rrwebEvent != null ) {
293- currentEvents + = rrwebEvent
294+ synchronized(currentEventsLock) {
295+ currentEvents + = rrwebEvent
296+ }
294297 }
295298 }
296299
297300 override fun close () {
298301 replayExecutor.gracefullyShutdown(options)
299302 }
300303
304+ protected fun rotateCurrentEvents (
305+ until : Long ,
306+ callback : ((RRWebEvent ) -> Unit )? = null,
307+ ) {
308+ synchronized(currentEventsLock) {
309+ var event = currentEvents.peek()
310+ while (event != null && event.timestamp <= until) {
311+ callback?.invoke(event)
312+ currentEvents.remove()
313+ event = currentEvents.peek()
314+ }
315+ }
316+ }
317+
301318 private class ReplayExecutorServiceThreadFactory : ThreadFactory {
302319 private var cnt = 0
303320 override fun newThread (r : Runnable ): Thread {
0 commit comments