@@ -75,6 +75,7 @@ @implementation SentryTracer {
7575 NSMutableArray <id <SentrySpan>> *_children;
7676 BOOL _startTimeChanged;
7777 NSDate *_originalStartTimestamp;
78+ NSObject *_idleTimeoutLock;
7879
7980#if SENTRY_HAS_UIKIT
8081 NSUInteger initTotalFrames;
@@ -125,6 +126,7 @@ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transacti
125126
126127 appStartMeasurement = [self getAppStartMeasurement ];
127128
129+ _idleTimeoutLock = [[NSObject alloc ] init ];
128130 if ([self hasIdleTimeout ]) {
129131 [self dispatchIdleTimeout ];
130132 }
@@ -164,26 +166,28 @@ - (nullable SentryTracer *)tracer
164166
165167- (void )dispatchIdleTimeout
166168{
167- if (_idleTimeoutBlock != nil ) {
168- [_configuration.dispatchQueueWrapper dispatchCancel: _idleTimeoutBlock];
169- }
170- __weak SentryTracer *weakSelf = self;
171- _idleTimeoutBlock = [_configuration.dispatchQueueWrapper createDispatchBlock: ^{
172- if (weakSelf == nil ) {
173- SENTRY_LOG_DEBUG (@" WeakSelf is nil. Not doing anything." );
174- return ;
169+ @synchronized (_idleTimeoutLock) {
170+ if (_idleTimeoutBlock != NULL ) {
171+ [_configuration.dispatchQueueWrapper dispatchCancel: _idleTimeoutBlock];
172+ }
173+ __weak SentryTracer *weakSelf = self;
174+ _idleTimeoutBlock = [_configuration.dispatchQueueWrapper createDispatchBlock: ^{
175+ if (weakSelf == nil ) {
176+ SENTRY_LOG_DEBUG (@" WeakSelf is nil. Not doing anything." );
177+ return ;
178+ }
179+ [weakSelf finishInternal ];
180+ }];
181+
182+ if (_idleTimeoutBlock == NULL ) {
183+ SENTRY_LOG_WARN (@" Couldn't create idle time out block. Can't schedule idle timeout. "
184+ @" Finishing transaction" );
185+ // If the transaction has no children, the SDK will discard it.
186+ [self finishInternal ];
187+ } else {
188+ [_configuration.dispatchQueueWrapper dispatchAfter: _configuration.idleTimeout
189+ block: _idleTimeoutBlock];
175190 }
176- [weakSelf finishInternal ];
177- }];
178-
179- if (_idleTimeoutBlock == NULL ) {
180- SENTRY_LOG_WARN (@" Couldn't create idle time out block. Can't schedule idle timeout. "
181- @" Finishing transaction" );
182- // If the transaction has no children, the SDK will discard it.
183- [self finishInternal ];
184- } else {
185- [_configuration.dispatchQueueWrapper dispatchAfter: _configuration.idleTimeout
186- block: _idleTimeoutBlock];
187191 }
188192}
189193
@@ -199,8 +203,10 @@ - (BOOL)isAutoGeneratedTransaction
199203
200204- (void )cancelIdleTimeout
201205{
202- if ([self hasIdleTimeout ]) {
203- [_configuration.dispatchQueueWrapper dispatchCancel: _idleTimeoutBlock];
206+ @synchronized (_idleTimeoutLock) {
207+ if ([self hasIdleTimeout ]) {
208+ [_configuration.dispatchQueueWrapper dispatchCancel: _idleTimeoutBlock];
209+ }
204210 }
205211}
206212
0 commit comments