Skip to content
This repository has been archived by the owner on May 19, 2018. It is now read-only.

Commit

Permalink
Completion handlers and cancellation handlers are dispatched immediat…
Browse files Browse the repository at this point in the history
…ely if the future has already been completed/cancelled.

Also corrects the tests, which had some race conditions due to the nondeterminism of the order of completion/cancellation handler execution and the fact that adding something to the actions set was done asynchronously.

Closes #1.
  • Loading branch information
robrix committed Feb 4, 2012
1 parent a2592fa commit 3d97924
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 13 deletions.
10 changes: 8 additions & 2 deletions RXFutures/RXFuture.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,19 @@ -(void)dispatchBlock:(void(^)())block {

-(void)onComplete:(void(^)())block {
dispatch_async(queue, ^{
[completionHandlers addObject:block];
if(completed)
[self dispatchBlock:block];
else
[completionHandlers addObject:block];
});
}

-(void)onCancel:(void(^)())block {
dispatch_async(queue, ^{
[cancellationHandlers addObject:block];
if(cancelled)
[self dispatchBlock:block];
else
[cancellationHandlers addObject:block];
});
}

Expand Down
44 changes: 33 additions & 11 deletions RXFuturesTests/RXFutureTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -80,25 +80,36 @@ -(void)testCompletionPrecludesCancellation {


-(void)addAction:(NSString *)action {
dispatch_async(queue, ^{
dispatch_sync(queue, ^{
[actions addObject:action];
});
}


-(void)testCallsCancellationHandlersOnCancellation {
[future onCancel:^{ [self addAction:@"a"]; }];
[future onCancel:^{ [self addAction:@"b"]; }];
RXSynchronously(^(RXSynchronousCompletionBlock done) {
[future onCancel:done];
[future onCancel:^{
[self addAction:@"a"];
done();
}];
[future cancel];
});
RXAssertEquals(actions, ([NSSet setWithObjects:@"a", @"b", nil]));
RXAssertEquals(actions, [NSSet setWithObject:@"a"]);
}

-(void)testCallsCancellationHandlersAddedAfterCancellation {
RXSynchronously(^(RXSynchronousCompletionBlock done) {
[future cancel];
[future onCancel:^{
[self addAction:@"a"];
done();
}];
});
RXAssertEquals(actions, [NSSet setWithObject:@"a"]);
}

-(void)testDoesNotCallCancellationHandlersOnCompletion {
[future onCancel:^{ [self addAction:@"a"]; }];
[future onCancel:^{ [self addAction:@"b"]; }];
RXSynchronously(^(RXSynchronousCompletionBlock done) {
[future onComplete:done];
[future complete];
Expand All @@ -108,18 +119,29 @@ -(void)testDoesNotCallCancellationHandlersOnCompletion {


-(void)testCallsCompletionHandlersOnCompletion {
[future onComplete:^{ [self addAction:@"a"]; }];
[future onComplete:^{ [self addAction:@"b"]; }];
RXSynchronously(^(RXSynchronousCompletionBlock done) {
[future onComplete:done];
[future onComplete:^{
[self addAction:@"a"];
done();
}];
[future complete];
});
RXAssertEquals(actions, ([NSSet setWithObjects:@"a", @"b", nil]));
RXAssertEquals(actions, [NSSet setWithObject:@"a"]);
}

-(void)testCallsCompletionHandlersAddedAfterCompletion {
RXSynchronously(^(RXSynchronousCompletionBlock done) {
[future complete];
[future onComplete:^{
[self addAction:@"a"];
done();
}];
});
RXAssertEquals(actions, [NSSet setWithObject:@"a"]);
}

-(void)testDoesNotCallCompletionHandlersOnCancellation {
[future onComplete:^{ [self addAction:@"a"]; }];
[future onComplete:^{ [self addAction:@"b"]; }];
RXSynchronously(^(RXSynchronousCompletionBlock done) {
[future onCancel:done];
[future cancel];
Expand Down

0 comments on commit 3d97924

Please sign in to comment.