Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions FirebaseDatabase/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Unreleased
- [fixed] Concurrency crash in FView. (#15514)

# 11.9.0
- [fixed] Fix connection failure issue introduced in 10.27.0 by restoring the
Socket Rocket implementation instead of `NSURLSessionWebSocket`. Note that
Expand Down
57 changes: 34 additions & 23 deletions FirebaseDatabase/Sources/Core/View/FView.m
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,15 @@ - (id)initWithQuery:(FQuerySpec *)query
}

- (BOOL)isEmpty {
return self.eventRegistrations.count == 0;
@synchronized(self.eventRegistrations) {
return self.eventRegistrations.count == 0;
}
}

- (void)addEventRegistration:(id<FEventRegistration>)eventRegistration {
[self.eventRegistrations addObject:eventRegistration];
@synchronized(self.eventRegistrations) {
[self.eventRegistrations addObject:eventRegistration];
}
}

/**
Expand All @@ -181,31 +185,35 @@ - (void)addEventRegistration:(id<FEventRegistration>)eventRegistration {
- (NSArray *)removeEventRegistration:(id<FEventRegistration>)eventRegistration
cancelError:(NSError *)cancelError {
NSMutableArray *cancelEvents = [[NSMutableArray alloc] init];
if (cancelError != nil) {
NSAssert(eventRegistration == nil,
@"A cancel should cancel all event registrations.");
FPath *path = self.query.path;
for (id<FEventRegistration> registration in self.eventRegistrations) {
FCancelEvent *maybeEvent =
[registration createCancelEventFromError:cancelError path:path];
if (maybeEvent) {
[cancelEvents addObject:maybeEvent];
@synchronized(self.eventRegistrations) {
if (cancelError != nil) {
NSAssert(eventRegistration == nil,
@"A cancel should cancel all event registrations.");
FPath *path = self.query.path;
for (id<FEventRegistration> registration in self
.eventRegistrations) {
FCancelEvent *maybeEvent =
[registration createCancelEventFromError:cancelError
path:path];
if (maybeEvent) {
[cancelEvents addObject:maybeEvent];
}
}
}
}

if (eventRegistration) {
NSUInteger i = 0;
while (i < self.eventRegistrations.count) {
id<FEventRegistration> existing = self.eventRegistrations[i];
if ([existing matches:eventRegistration]) {
[self.eventRegistrations removeObjectAtIndex:i];
} else {
i++;
if (eventRegistration) {
NSUInteger i = 0;
while (i < self.eventRegistrations.count) {
id<FEventRegistration> existing = self.eventRegistrations[i];
if ([existing matches:eventRegistration]) {
[self.eventRegistrations removeObjectAtIndex:i];
} else {
i++;
}
}
} else {
[self.eventRegistrations removeAllObjects];
}
} else {
[self.eventRegistrations removeAllObjects];
}
return cancelEvents;
}
Expand Down Expand Up @@ -270,7 +278,10 @@ - (NSArray *)generateEventsForChanges:(NSArray *)changes
registration:(id<FEventRegistration>)registration {
NSArray *registrations;
if (registration == nil) {
registrations = [[NSArray alloc] initWithArray:self.eventRegistrations];
@synchronized(self.eventRegistrations) {
registrations =
[[NSArray alloc] initWithArray:self.eventRegistrations];
}
} else {
registrations = [[NSArray alloc] initWithObjects:registration, nil];
}
Expand Down
Loading