site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com G'day Duane, Cheers Godfrey van der Linden On 2008-08-13, at 12:30 , Duane Murphy wrote: Thanks Chris. I get the gist of how this works... --- At Wed, 13 Aug 2008 10:27:53 -0700, Chris Sarcone wrote: Duane - Easy recipe: Sync Call is made done = false; Send I/O asynchronously IOCommandGate::runAction() while (!done) IOCommandGate::commandSleep(&done,TH_UNINT); On workloop completion thread: done = true; IOCommandGate::commandWakeup(&done); This is the part that I'm usually confused on. Does the thread have to have the gate to call commandWakeup or can commandWakeup be called anytime? Thanks again. This was very helpful. ...Duane _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/gvdl%40mac.com _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... I pretty sure that all block storage completion routines are called from a workloop context. I.e. the runAction() is actually performed for you by an interrupt event source way, way down on the stack. This is the basic model of threading in I/O Kit, your completion routines are always called in a 'gated' context. So if you want to synchronise with such a routine you also need to use a commandGate. Thus when you need to block a thread --- aka put to sleep --- decision to block the thread must be made while gated, this is where the command gate::runAction comes into use as described be ChrisS. Once you decide that you need to sleep here it is simply a matter of blocking the thread with commandSleep, which blocks your thread and drops the gate so other threads can make progress. When the threading model was designed we modelled the gated target/ action concepts on the Java Synchronous routine threading, though without language support there was never any easy way to make it elegant. Any action routine called by an event source, like interrupt, timeout of even command actions are guaranteed to be single threaded against the IOWorkLoop that are registered with. No matter how many drivers there are on a stack there usually all synch against one workloop. It can, and has been with some force, argued that this model is both unconventional and over engineered. However it does have a couple of very nice advantages over lock based threading. There is no way to lose count of how many times a recursive lock is taken so error paths always release locks cleanly. Another huge advantage is that taking the lock --- closing the gate in IOKit speak --- is always represented with a function call on the stack. So if you think you have caused a deadlock 'showallstacks' in gdb will always show it. This dug Apple out of the poo many many times during Darwin's early development. What is the recipe for this seemingly simple task (that IOSyncer handles very nicely) with IOCommandGate. The completion thread is the callback for the completion of IO (IOStorageCompletion). Can that callback just call commandWakeup or do I have to enter the gate first using runAction and call commandWakeup from the runAction call back? This email sent to gvdl@mac.com This email sent to site_archiver@lists.apple.com