nevyn/SPAsync — pull request #4 by btgerst (2013-08-19 16:54:20+00:00)
Title: Tests and fixes for awaitAll behavior

I ran into a scenario that consistently caused an uncaught exception in `+[SPTask awaitAll:]` at the line with `[values replaceObjectAtIndex:...]`. The problem was that one of the tasks in my await group was failing, after which another task completed, causing the await source to attempt mutating `values` after it had already been emptied (thus throwing an exception). I added a test case which can reproduce this crash (`[SPTaskTest testAwaitAll_FailThenComplete]`) along with a couple other tests on this theme.

One thing I did in the fixes was to check `if ([remainingTasks count] == 0])`, which is only really necessary since we throw an assertion if a `SPTaskCompletionSource` is sent more than one call to either `completeWithValue:` or `failWithError:`. I'm not sure how I feel about this behavior, as I think ignoring the second call (as is done in multiple calls to `cancel`) would be less troublesome and not introduce any significant vulnerabilities.