Skip to content

Commit 6a9dcc2

Browse files
Fix a potential deadlock that could occur when encoding for REST.
We didn't actually need to hold the lock here, and if we did, another thread could have acquired these locks in another order, causing a deadlock. Should help to fix #398, #11, and a few others.
1 parent 31c8143 commit 6a9dcc2

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed

Parse/Internal/Object/PFObjectPrivate.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@
220220
- (NSDictionary *)RESTDictionaryWithObjectEncoder:(PFEncoder *)objectEncoder
221221
operationSetUUIDs:(NSArray **)operationSetUUIDs
222222
state:(PFObjectState *)state
223-
operationSetQueue:(NSArray *)operationSetQueue;
223+
operationSetQueue:(NSArray *)queue
224+
deletingEventually:(BOOL)isDeletingEventually;
224225

225226
- (void)mergeFromRESTDictionary:(NSDictionary *)object
226227
withDecoder:(PFDecoder *)decoder;

Parse/PFObject.m

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -958,25 +958,33 @@ + (BFTask *)_migrateObjectInBackgroundFromFile:(NSString *)fileName
958958
*/
959959
- (NSDictionary *)RESTDictionaryWithObjectEncoder:(PFEncoder *)objectEncoder
960960
operationSetUUIDs:(NSArray **)operationSetUUIDs {
961+
NSArray *operationQueue = nil;
962+
PFObjectState *state = nil;
963+
BOOL deleting = NO;
961964
@synchronized (lock) {
962965
[self checkForChangesToMutableContainers];
963-
PFObjectState *state = self._state;
964-
return [self RESTDictionaryWithObjectEncoder:objectEncoder
965-
operationSetUUIDs:operationSetUUIDs
966-
state:state
967-
operationSetQueue:operationSetQueue];
966+
state = self._state;
967+
operationQueue = [[NSArray alloc] initWithArray:operationSetQueue copyItems:YES];
968+
deleting = _deletingEventually;
968969
}
970+
971+
return [self RESTDictionaryWithObjectEncoder:objectEncoder
972+
operationSetUUIDs:operationSetUUIDs
973+
state:state
974+
operationSetQueue:operationQueue
975+
deletingEventually:deleting];
969976
}
970977

971978
- (NSDictionary *)RESTDictionaryWithObjectEncoder:(PFEncoder *)objectEncoder
972979
operationSetUUIDs:(NSArray **)operationSetUUIDs
973980
state:(PFObjectState *)state
974-
operationSetQueue:(NSArray *)queue {
981+
operationSetQueue:(NSArray *)queue
982+
deletingEventually:(BOOL)isDeletingEventually {
975983
NSMutableDictionary *result = [[state dictionaryRepresentationWithObjectEncoder:objectEncoder] mutableCopy];
976984
result[PFObjectClassNameRESTKey] = state.parseClassName;
977985
result[PFObjectCompleteRESTKey] = @(state.complete);
978986

979-
result[PFObjectIsDeletingEventuallyRESTKey] = @(_deletingEventually);
987+
result[PFObjectIsDeletingEventuallyRESTKey] = @(isDeletingEventually);
980988

981989
// TODO (hallucinogen): based on some note from Android's toRest, we'll need to put this
982990
// stuff somewhere else

Parse/PFUser.m

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,8 @@ - (void)mergeFromRESTDictionary:(NSDictionary *)object withDecoder:(PFDecoder *)
650650
- (NSDictionary *)RESTDictionaryWithObjectEncoder:(PFEncoder *)objectEncoder
651651
operationSetUUIDs:(NSArray **)operationSetUUIDs
652652
state:(PFObjectState *)state
653-
operationSetQueue:(NSArray *)queue {
653+
operationSetQueue:(NSArray *)queue
654+
deletingEventually:(BOOL)isDeletingEventually {
654655
@synchronized (self.lock) {
655656
NSMutableArray *cleanQueue = [queue mutableCopy];
656657
[queue enumerateObjectsUsingBlock:^(PFOperationSet *operationSet, NSUInteger idx, BOOL *stop) {
@@ -665,7 +666,8 @@ - (NSDictionary *)RESTDictionaryWithObjectEncoder:(PFEncoder *)objectEncoder
665666
return [super RESTDictionaryWithObjectEncoder:objectEncoder
666667
operationSetUUIDs:operationSetUUIDs
667668
state:state
668-
operationSetQueue:cleanQueue];
669+
operationSetQueue:cleanQueue
670+
deletingEventually:isDeletingEventually];
669671
}
670672
}
671673

0 commit comments

Comments
 (0)