|  | 
| 38 | 38 | /// The storage sub-directory that the Remote Config database resides in. | 
| 39 | 39 | static NSString *const RCNRemoteConfigStorageSubDirectory = @"Google/RemoteConfig"; | 
| 40 | 40 | 
 | 
|  | 41 | +/// Introduce a dedicated serial queue for gIsNewDatabase access. | 
|  | 42 | +static dispatch_queue_t gIsNewDatabaseQueue; | 
|  | 43 | + | 
| 41 | 44 | /// Remote Config database path for deprecated V0 version. | 
| 42 | 45 | static NSString *RemoteConfigPathForOldDatabaseV0(void) { | 
| 43 | 46 |   NSArray *dirPaths = | 
| @@ -80,11 +83,11 @@ static BOOL RemoteConfigCreateFilePathIfNotExist(NSString *filePath) { | 
| 80 | 83 |                 @"Failed to create subdirectory for an empty file path."); | 
| 81 | 84 |     return NO; | 
| 82 | 85 |   } | 
| 83 |  | -  FIRLogDebug(kFIRLoggerRemoteConfig, @"RC-SDK-DEBUG", @"DBManager: DB file does not exists BEFORE create: 0"); | 
| 84 | 86 |   NSFileManager *fileManager = [NSFileManager defaultManager]; | 
| 85 | 87 |   if (![fileManager fileExistsAtPath:filePath]) { | 
| 86 |  | -    FIRLogDebug(kFIRLoggerRemoteConfig, @"RC-SDK-DEBUG", @"DBManager: Setting gIsNewDatabase = YES"); | 
| 87 |  | -    gIsNewDatabase = YES; | 
|  | 88 | +    dispatch_sync(gIsNewDatabaseQueue, ^{ | 
|  | 89 | +      gIsNewDatabase = YES; | 
|  | 90 | +    }); | 
| 88 | 91 |     NSError *error; | 
| 89 | 92 |     [fileManager createDirectoryAtPath:[filePath stringByDeletingLastPathComponent] | 
| 90 | 93 |            withIntermediateDirectories:YES | 
| @@ -121,6 +124,8 @@ + (instancetype)sharedInstance { | 
| 121 | 124 |   static dispatch_once_t onceToken; | 
| 122 | 125 |   static RCNConfigDBManager *sharedInstance; | 
| 123 | 126 |   dispatch_once(&onceToken, ^{ | 
|  | 127 | +    gIsNewDatabaseQueue = dispatch_queue_create("com.google.FirebaseRemoteConfig.gIsNewDatabase", | 
|  | 128 | +                                                DISPATCH_QUEUE_SERIAL); | 
| 124 | 129 |     sharedInstance = [[RCNConfigDBManager alloc] init]; | 
| 125 | 130 |   }); | 
| 126 | 131 |   return sharedInstance; | 
| @@ -1221,7 +1226,20 @@ - (BOOL)logErrorWithSQL:(const char *)SQL | 
| 1221 | 1226 | } | 
| 1222 | 1227 | 
 | 
| 1223 | 1228 | - (BOOL)isNewDatabase { | 
| 1224 |  | -  return gIsNewDatabase; | 
|  | 1229 | +  __block BOOL isNew; | 
|  | 1230 | +  dispatch_sync(gIsNewDatabaseQueue, ^{ | 
|  | 1231 | +    isNew = gIsNewDatabase; | 
|  | 1232 | +  }); | 
|  | 1233 | +  return isNew; | 
|  | 1234 | +} | 
|  | 1235 | + | 
|  | 1236 | +- (void)waitForDatabaseOperationQueue { | 
|  | 1237 | +  // This dispatch_sync call ensures that all blocks queued before it on _databaseOperationQueue | 
|  | 1238 | +  // (including the createOrOpenDatabase setup block) execute and complete before this method | 
|  | 1239 | +  // returns. | 
|  | 1240 | +  dispatch_sync(_databaseOperationQueue, ^{ | 
|  | 1241 | +                    // Empty block forces synchronization. | 
|  | 1242 | +                }); | 
| 1225 | 1243 | } | 
| 1226 | 1244 | 
 | 
| 1227 | 1245 | @end | 
0 commit comments