Option to elevate a running block to a barrier block

Originator:michaelhochs
Number:rdar://37308258 Date Originated:07-Feb-2018 11:35 AM
Status:Open Resolved:
Product:iOS + SDK Product Version:11
Classification:Enhancement Reproducible:Always
 
Summary:
I think it would be a great addition to GCD if I could elevate a block to become a barrier block after it started to execute.

Given a concurrent queue, dispatching a block on it, at some point I want to call something like dispatch_barrier_wait(); or something similar that elevates the current block to a barrier block, waits for other concurrently executing blocks to finish and than continues like a regular barrier block. There is the case where multiple blocks try this at the same time though, so this method would need to return a BOOL, communicating if this worked or if the block is still a concurrently executing block.

This would be very helpful for cases like lazy getters in a parallel environment. It would be beneficial in a lot of cases that use the pattern to read synchronously and parallel but write in a barrier block.

For example:

```
- (NSUInteger)someValue {
    __block NSUInteger value;
    dispatch_sync(self.lockQueue, ^{
        if (self->_value == NSUIntegerMax) {
            BOOL success = dispatch_barrier_wait();
            if (success) {
                self->_value = [self calculateSomeValue];
            } else {
                // fall back to current behavior: leave queue, dispatch into it again with a barrier block
            }
        }
        value = self->_value;
    });
    return value;
}
```

In cases like this it is acceptable to wait for the barrier to take effect because the other option would be to leave the queue and dispatch into it again in a barrier block, which presumably would take more time.

Another benefit of this approach is: Due to the business logic in cases like these I know for sure that when this succeeds no other barrier block could have been executed in the meantime; so for my use case I know for sure that the ivar has not been altered in the meantime. This means I save the extra time to read the ivar again, which I would need to do if I leave the block and dispatch into it again in a barrier block to alter the ivar.

Steps to Reproduce:
 

Expected Results:
 

Actual Results:
 

Version:
11

Notes:

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!