Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIRApp: thread safety fixes #2639

Merged
merged 2 commits into from Mar 26, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
59 changes: 35 additions & 24 deletions Firebase/Core/FIRApp.m
Expand Up @@ -166,9 +166,11 @@ + (void)configureWithName:(NSString *)name options:(FIROptions *)options {
}
}

if (sAllApps && sAllApps[name]) {
[NSException raise:kFirebaseCoreErrorDomain
format:@"App named %@ has already been configured.", name];
@synchronized(self) {
if (sAllApps && sAllApps[name]) {
[NSException raise:kFirebaseCoreErrorDomain
format:@"App named %@ has already been configured.", name];
}
}

FIRLogDebug(kFIRLoggerCore, @"I-COR000002", @"Configuring app named %@", name);
Expand Down Expand Up @@ -214,18 +216,19 @@ + (NSDictionary *)allApps {
if (!sAllApps) {
FIRLogError(kFIRLoggerCore, @"I-COR000005", @"No app has been configured yet.");
}
NSDictionary *dict = [NSDictionary dictionaryWithDictionary:sAllApps];
return dict;
return [sAllApps copy];
}
}

// Public only for tests
+ (void)resetApps {
sDefaultApp = nil;
[sAllApps removeAllObjects];
sAllApps = nil;
[sLibraryVersions removeAllObjects];
sLibraryVersions = nil;
@synchronized(self) {
sDefaultApp = nil;
[sAllApps removeAllObjects];
sAllApps = nil;
[sLibraryVersions removeAllObjects];
sLibraryVersions = nil;
}
}

- (void)deleteApp:(FIRAppVoidBoolCallback)completion {
Expand Down Expand Up @@ -423,8 +426,10 @@ + (void)sendNotificationsToSDKs:(FIRApp *)app {

// This is the new way of sending information to SDKs.
// TODO: Do we want this on a background thread, maybe?
for (Class<FIRLibrary> library in sRegisteredAsConfigurable) {
[library configureWithApp:app];
@synchronized(self) {
for (Class<FIRLibrary> library in sRegisteredAsConfigurable) {
[library configureWithApp:app];
}
}
}

Expand Down Expand Up @@ -476,10 +481,12 @@ + (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *
// add the name/version pair to the dictionary.
if ([name rangeOfCharacterFromSet:disallowedSet].location == NSNotFound &&
[version rangeOfCharacterFromSet:disallowedSet].location == NSNotFound) {
if (!sLibraryVersions) {
sLibraryVersions = [[NSMutableDictionary alloc] init];
@synchronized(self) {
if (!sLibraryVersions) {
sLibraryVersions = [[NSMutableDictionary alloc] init];
}
sLibraryVersions[name] = version;
}
sLibraryVersions[name] = version;
} else {
FIRLogError(kFIRLoggerCore, @"I-COR000027",
@"The library name (%@) or version number (%@) contain invalid characters. "
Expand Down Expand Up @@ -508,20 +515,24 @@ + (void)registerInternalLibrary:(nonnull Class<FIRLibrary>)library
dispatch_once(&onceToken, ^{
sRegisteredAsConfigurable = [[NSMutableArray alloc] init];
});
[sRegisteredAsConfigurable addObject:library];
@synchronized(self) {
[sRegisteredAsConfigurable addObject:library];
}
}
[self registerLibrary:name withVersion:version];
}

+ (NSString *)firebaseUserAgent {
NSMutableArray<NSString *> *libraries =
[[NSMutableArray<NSString *> alloc] initWithCapacity:sLibraryVersions.count];
for (NSString *libraryName in sLibraryVersions) {
[libraries
addObject:[NSString stringWithFormat:@"%@/%@", libraryName, sLibraryVersions[libraryName]]];
}
[libraries sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
return [libraries componentsJoinedByString:@" "];
@synchronized(self) {
NSMutableArray<NSString *> *libraries =
[[NSMutableArray<NSString *> alloc] initWithCapacity:sLibraryVersions.count];
for (NSString *libraryName in sLibraryVersions) {
[libraries addObject:[NSString stringWithFormat:@"%@/%@", libraryName,
sLibraryVersions[libraryName]]];
}
[libraries sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
return [libraries componentsJoinedByString:@" "];
}
}

- (void)checkExpectedBundleID {
Expand Down