From 440e2f0b71e33f74114cf87cf723093ae525ee52 Mon Sep 17 00:00:00 2001 From: Thomas Van Lenten Date: Thu, 4 Jun 2026 09:10:37 -0400 Subject: [PATCH] Avoid some more potential data race conditions. Use `dispatch_once` instead of a `static BOOL` to guard the work. While at it, remove one use of `@synchronized` to instead standardize on just `dispatch_once`. --- Sources/Core/GTLRBase64.m | 16 ++++++---------- Sources/Core/GTLRRuntimeCommon.m | 7 +++---- Sources/Core/GTLRUtilities.m | 15 +++++++-------- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/Sources/Core/GTLRBase64.m b/Sources/Core/GTLRBase64.m index 989dd7048..1126ef5d4 100644 --- a/Sources/Core/GTLRBase64.m +++ b/Sources/Core/GTLRBase64.m @@ -119,24 +119,20 @@ static void CreateDecodingTable(const char *encodingTable, NSData *GTLRDecodeBase64(NSString *base64Str) { static char decodingTable[128]; - static BOOL hasInited = NO; - - if (!hasInited) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ CreateDecodingTable(gStandardEncodingTable, sizeof(gStandardEncodingTable), decodingTable); - hasInited = YES; - } + }); return DecodeBase64StringCommon(base64Str, decodingTable, YES /* requirePadding */ ); } NSData *GTLRDecodeWebSafeBase64(NSString *base64Str) { static char decodingTable[128]; - static BOOL hasInited = NO; - - if (!hasInited) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ CreateDecodingTable(gWebSafeEncodingTable, sizeof(gWebSafeEncodingTable), decodingTable); - hasInited = YES; - } + }); return DecodeBase64StringCommon(base64Str, decodingTable, NO /* requirePadding */); } diff --git a/Sources/Core/GTLRRuntimeCommon.m b/Sources/Core/GTLRRuntimeCommon.m index b967083e5..b999776f0 100644 --- a/Sources/Core/GTLRRuntimeCommon.m +++ b/Sources/Core/GTLRRuntimeCommon.m @@ -484,11 +484,10 @@ typedef NS_ENUM(NSUInteger, GTLRPropertyType) { }, }; - static BOOL hasLookedUpClasses = NO; - if (!hasLookedUpClasses) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ // Unfortunately, you can't put [NSString class] into the static structure, // so this lookup has to be done at runtime. - hasLookedUpClasses = YES; for (uint32_t idx = 0; idx < sizeof(kImplInfo)/sizeof(kImplInfo[0]); ++idx) { if (kImplInfo[idx].returnClassName) { kImplInfo[idx].returnClass = objc_getClass(kImplInfo[idx].returnClassName); @@ -496,7 +495,7 @@ typedef NS_ENUM(NSUInteger, GTLRPropertyType) { @"GTLRRuntimeCommon: class lookup failed: %s", kImplInfo[idx].returnClassName); } } - } + }); const char *attr = property_getAttributes(prop); diff --git a/Sources/Core/GTLRUtilities.m b/Sources/Core/GTLRUtilities.m index efdf84aee..017844f13 100644 --- a/Sources/Core/GTLRUtilities.m +++ b/Sources/Core/GTLRUtilities.m @@ -85,14 +85,13 @@ BOOL GTLR_AreBoolsEqual(BOOL b1, BOOL b2) { if ([str rangeOfString:@"."].location != NSNotFound) { // This is a floating-point number. // Force the parser to use '.' as the decimal separator. - static NSLocale *usLocale = nil; - @synchronized([GTLRUtilities class]) { - if (usLocale == nil) { - usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; - } - newNum = [NSDecimalNumber decimalNumberWithString:(NSString*)num - locale:(id)usLocale]; - } + static NSLocale *usLocale; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; + }); + newNum = [NSDecimalNumber decimalNumberWithString:(NSString*)num + locale:(id)usLocale]; } else { // NSDecimalNumber +decimalNumberWithString:locale: // does not correctly create an NSNumber for large values like