diff options
author | Joel Fischer <joeljfischer@gmail.com> | 2020-02-26 09:52:43 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-26 09:52:43 -0500 |
commit | e012a547fb54da56baef5ea309eb35743b3875d1 (patch) | |
tree | 520b631d7f4d4811e828f978148d77350d36caf3 | |
parent | bf64195c1d8d33a6ac59421cd6380798bd3ba86d (diff) | |
parent | 4da610726f9a1453bbffc0d88589add532980b26 (diff) | |
download | sdl_ios-e012a547fb54da56baef5ea309eb35743b3875d1.tar.gz |
Merge pull request #1570 from smartdevicelink/bugfix/issue-1564-correlationId-thread-safety
Ensure RPC Request thread safety
-rw-r--r-- | SmartDeviceLink/SDLGlobals.h | 3 | ||||
-rw-r--r-- | SmartDeviceLink/SDLGlobals.m | 8 | ||||
-rw-r--r-- | SmartDeviceLink/SDLLifecycleManager.m | 31 |
3 files changed, 24 insertions, 18 deletions
diff --git a/SmartDeviceLink/SDLGlobals.h b/SmartDeviceLink/SDLGlobals.h index 2d4edf017..004a0e8d9 100644 --- a/SmartDeviceLink/SDLGlobals.h +++ b/SmartDeviceLink/SDLGlobals.h @@ -26,6 +26,9 @@ extern NSUInteger const SDLDefaultMTUSize; extern NSUInteger const SDLV1MTUSize; extern NSUInteger const SDLV3MTUSize; +extern void *const SDLProcessingQueueName; +extern void *const SDLConcurrentQueueName; + @interface SDLGlobals : NSObject @property (copy, nonatomic, readonly) SDLVersion *protocolVersion; diff --git a/SmartDeviceLink/SDLGlobals.m b/SmartDeviceLink/SDLGlobals.m index dfff3ca50..dc78e7a56 100644 --- a/SmartDeviceLink/SDLGlobals.m +++ b/SmartDeviceLink/SDLGlobals.m @@ -22,6 +22,8 @@ NSUInteger const SDLDefaultMTUSize = UINT32_MAX; NSUInteger const SDLV1MTUSize = 1024; NSUInteger const SDLV3MTUSize = 131024; +void *const SDLProcessingQueueName = "com.sdl.serialProcessing"; +void *const SDLConcurrentQueueName = "com.sdl.concurrentProcessing"; typedef NSNumber *ServiceTypeBox; typedef NSNumber *MTUBox; @@ -61,8 +63,10 @@ typedef NSNumber *MTUBox; dispatch_queue_attr_t qosSerial = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, 0); dispatch_queue_attr_t qosConcurrent = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_USER_INITIATED, 0); - _sdlProcessingQueue = dispatch_queue_create("com.sdl.serialProcessing", qosSerial); - _sdlConcurrentQueue = dispatch_queue_create("com.sdl.concurrentProcessing", qosConcurrent); + _sdlProcessingQueue = dispatch_queue_create(SDLProcessingQueueName, qosSerial); + dispatch_queue_set_specific(_sdlProcessingQueue, SDLProcessingQueueName, SDLProcessingQueueName, NULL); + _sdlConcurrentQueue = dispatch_queue_create(SDLConcurrentQueueName, qosConcurrent); + dispatch_queue_set_specific(_sdlConcurrentQueue, SDLConcurrentQueueName, SDLConcurrentQueueName, NULL); return self; } diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 05a09dd9b..5977ded75 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -342,7 +342,7 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask // Send the request and depending on the response, post the notification __weak typeof(self) weakSelf = self; - [self sdl_sendRequest:regRequest + [self sendConnectionManagerRequest:regRequest withResponseHandler:^(__kindof SDLRPCRequest *_Nullable request, __kindof SDLRPCResponse *_Nullable response, NSError *_Nullable error) { // If the success BOOL is NO or we received an error at this point, we failed. Call the ready handler and transition to the DISCONNECTED state. if (error != nil || ![response.success boolValue]) { @@ -587,7 +587,7 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask SDLSetAppIcon *setAppIcon = [[SDLSetAppIcon alloc] init]; setAppIcon.syncFileName = appIcon.name; - [self sdl_sendRequest:setAppIcon + [self sendConnectionManagerRequest:setAppIcon withResponseHandler:^(__kindof SDLRPCRequest *_Nullable request, __kindof SDLRPCResponse *_Nullable response, NSError *_Nullable error) { if (error != nil) { SDLLogW(@"Error setting up app icon: %@", error); @@ -651,7 +651,9 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask return; } - [self sdl_sendRequest:rpc withResponseHandler:nil]; + [self sdl_runOnProcessingQueue:^{ + [self sdl_sendRequest:rpc withResponseHandler:nil]; + }]; } - (void)sendConnectionRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { @@ -676,13 +678,17 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask return; } - - [self sdl_sendRequest:request withResponseHandler:handler]; + + [self sdl_runOnProcessingQueue:^{ + [self sdl_sendRequest:request withResponseHandler:handler]; + }]; } // Managers need to avoid state checking. Part of <SDLConnectionManagerType>. - (void)sendConnectionManagerRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { - [self sdl_sendRequest:request withResponseHandler:handler]; + [self sdl_runOnProcessingQueue:^{ + [self sdl_sendRequest:request withResponseHandler:handler]; + }]; } - (void)sdl_sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { @@ -733,8 +739,7 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask // this is to make sure that the transition happens on the dedicated queue - (void)sdl_runOnProcessingQueue:(void (^)(void))block { - if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(self.lifecycleQueue)) == 0 - || strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label([SDLGlobals sharedGlobals].sdlProcessingQueue)) == 0) { + if (dispatch_get_specific(SDLProcessingQueueName) != nil) { block(); } else { dispatch_sync(self.lifecycleQueue, block); @@ -742,15 +747,9 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask } - (void)sdl_transitionToState:(SDLState *)state { - if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(self.lifecycleQueue)) == 0 - || strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label([SDLGlobals sharedGlobals].sdlProcessingQueue)) == 0) { + [self sdl_runOnProcessingQueue:^{ [self.lifecycleStateMachine transitionToState:state]; - } else { - // once this method returns, the transition is completed - dispatch_sync(self.lifecycleQueue, ^{ - [self.lifecycleStateMachine transitionToState:state]; - }); - } + }]; } /** |