Skip to content

Commit

Permalink
Merge pull request #1592 from smartdevicelink/bugfix/issue_1583_iAP_s…
Browse files Browse the repository at this point in the history
…top_session_crash

Fixed crash when an iAP control session is stopped
  • Loading branch information
joeljfischer committed Apr 14, 2020
2 parents 681084d + 572b42b commit e58fae4
Showing 1 changed file with 28 additions and 16 deletions.
44 changes: 28 additions & 16 deletions SmartDeviceLink/SDLIAPControlSession.m
Expand Up @@ -54,27 +54,39 @@ - (void)startSession {
} else {
SDLLogD(@"Starting a control session with accessory (%@)", self.accessory.name);

if (![self sdl_startStreams]) {
SDLLogW(@"Control session failed to setup with accessory: %@. Attempting to create a new control session", self.accessory);
[self destroySession];
if (self.delegate == nil) { return; }
[self.delegate controlSessionShouldRetry];
} else {
SDLLogD(@"Waiting for the protocol string from Core, setting timer for %d seconds", ProtocolIndexTimeoutSeconds);
self.protocolIndexTimer = [self sdl_createControlSessionProtocolIndexStringDataTimeoutTimer];
}
__weak typeof(self) weakSelf = self;
[self sdl_startStreamsWithCompletionHandler:^(BOOL success) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!success) {
SDLLogW(@"Control session failed to setup with accessory: %@. Attempting to create a new control session", strongSelf.accessory);
[strongSelf destroySession];
if (strongSelf.delegate == nil) { return; }
[strongSelf.delegate controlSessionShouldRetry];
} else {
SDLLogD(@"Waiting for the protocol string from Core, setting timeout timer for %d seconds", ProtocolIndexTimeoutSeconds);
strongSelf.protocolIndexTimer = [strongSelf sdl_createControlSessionProtocolIndexStringDataTimeoutTimer];
}
}];
}
}

- (BOOL)sdl_startStreams {
if (![super createSession]) { return NO; }
/// Opens the input and output streams for the session on the main thread.
/// @discussion We must close the input/output streams from the same thread that owns the streams' run loop, otherwise if the streams are closed from another thread a random crash may occur. Since only a small amount of data will be transmitted on this stream before it is closed, we will open and close the streams on the main thread instead of creating a separate thread.
- (void)sdl_startStreamsWithCompletionHandler:(void (^)(BOOL success))completionHandler {
if (![super createSession]) {
return completionHandler(NO);
}

__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(weakSelf) strongSelf = weakSelf;

// No need for its own thread as only a small amount of data will be transmitted before control session is destroyed
SDLLogD(@"Created the control session successfully");
[super startStream:self.eaSession.outputStream];
[super startStream:self.eaSession.inputStream];
SDLLogD(@"Created the control session successfully");
[super startStream:strongSelf.eaSession.outputStream];
[super startStream:strongSelf.eaSession.inputStream];

return YES;
return completionHandler(YES);
});
}

#pragma mark Stop
Expand Down

0 comments on commit e58fae4

Please sign in to comment.