Re: Can I create a thread with a runloop and a dispatch queue?
Re: Can I create a thread with a runloop and a dispatch queue?
- Subject: Re: Can I create a thread with a runloop and a dispatch queue?
- From: Andreas Grosam <email@hidden>
- Date: Sat, 05 Oct 2013 16:34:19 +0200
On 04.10.2013, at 19:16, Jens Alfke <email@hidden> wrote:
>
> On Oct 4, 2013, at 4:08 AM, Andreas Grosam <email@hidden> wrote:
>
>> Scheduling or dispatching a callback or block onto a "known" thread/queue will increase the risk for a dead lock. Thus, the execution context of the callback shall be created/selected by the "asynchronous result provider" and should not be accessible by the call-site.
>
> It seems the other way around to me. If (as I suggested) the implementation schedules the callback on a caller-selected queue, it’s asynchronous and the worker queue keeps going. But, if the implementation calls the callback directly from its internal worker queue, it’s now at the mercy of the caller — it has no idea how long that block will take to execute, and the internal worker queue can’t handle any more requests until the caller’s block returns. In the worst case, the caller’s block could try to execute another request synchronously and that _would_ deadlock:
> [foo doSomethingAndThen: ^{
> x = [foo doSomethingElseAndReturnResultSynchronously];
> }];
> If the block above is called on foo’s worker queue, this code will deadlock because the queue will never be able to process the ‘doSomethingElse’ request.
>
> Basically, by calling a client-supplied block on its private internal queue, the implementation is exposing sensitive internal state to its callers. That seems like a really bad idea.
Indeed, this would be a bad idea, thus the implementation of the asynchronous task wouldn't call a block on its private *worker* queues. Instead, the async task selects or creates a private queue to execute the completion block and pass the eventual result:
- (void) finished {
completion_t block = self.completionHandler;
if (block) {
id result = self.result;
dispatch_async(dispatch_get_global_queue(0, 0), {
block(result);
});
}
self.isExecuting = NO;
self.isFinished = YES;
_self = nil; // this may dealloc "self"
}
This is how NSOperation is implemented, for example.
Andreas
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden