Re: Two Kext Locking Question
Re: Two Kext Locking Question
- Subject: Re: Two Kext Locking Question
- From: Scott Taggart <email@hidden>
- Date: Fri, 28 Jun 2002 11:42:58 -0700
I'm a bit lost on something below... (thanks in advance)
At 11:03 AM 6/28/2002, Godfrey van der Linden wrote:
>
The IOCommandGate is designed to do this, check out the header doc.
>
>
However I wrote a paper on designing a PCI device quite a while ago which
>
should still be available on RobB's How too site.
>
>
In simple explanation is that the workloop is the master lock for one
>
driver stack. In your case kext A will be registering with your
>
provider's workloop. Now a work loop has lots of event sources registered
>
with it and each event source has an associated Action. It is guaranteed
>
that one and only one Action routine can run on a particular workloop at
>
any time.
>
>
So in your example if you find your workloop by just calling
>
provider->getWorkLoop() in KextA you will automatically be able to
>
synchronise with the USBs work loop and all completion routines come out
>
on that context. Then if you need to protect your own driver against
>
these completion routines and you addEventSource() them to your providers
>
work loop. Note it is also OK to add IOTimerEventSources if you have
>
times outs. (Note however the IOTimerEventSource doesn't currently have a
>
reliable cancel path so be very careful when you are trying to unload your
>
driver.)
>
>
Then In the APIs from your client you wish to synchronise you use the
>
fGate->runAction(...) function.
>
>
Pseudo code follows (check header doc for details).
>
>
in your start routine in Kext A
>
>
fGate = IOCommandGate::commandGate(this);
>
IOWorkLoop *wl = getWorkLoop(); // Find my providers work loop.
>
if (!fGate || !wl)
>
return false;
>
if (kIOReturnSuccess != wl->addEventSource(fGate))
>
return false;
>
// That's it your now have an IOCommandGate set up in member variable fGate
>
>
IOReturn KextA::myClientsAPI(args)
>
{
>
return fGate->runAction(&KextA::myClientsAPIGated, args);
>
}
In my comments, I am assuming that Kext B calls your below static function
named myClientsAPIGated.... Two things I don't understand about what you
show in the above myClientsAPI()... First, the way you show the
myClientsAPI() method above, it looks like it's a non-static method being
called by some other member-function of KextA:: -- while this may be useful
somewhere else, I need KextB to be able to call into the static function
you show below, grab the gate and then call KextA::xxx members. It seems
like you are showing this the other way around, or do I not understand what
"runAction" is doing? Here's what I envision (is this right??):
// this is static...
IOReturn KextA::KextBEntry(IOService *servSelf,...)
{
KextA *self = (KextA *) servSelf;
self->GoFromB(...);
}
// next 2 are non-static
IOReturn KextA::GoFromB(...)
{
return fGate->runAction(&KextA::DoSomethingFinally, ...);
}
IOReturn KextA::DoSomethingFinally(...)
{
// do gate-protected stuff here
}
>
// Make sure this function is declared as a 'static' function in the header
>
IOReturn KextA::myClientsAPIGated(IOService *servSelf, void *vArg1, void
>
*vArg2, /*etc ... */ )
>
{
>
KextA *self = (KextA *) servSelf;
>
UInt32 arg1 = (UInt32) vArg1;
>
>
// You can see where this is going I'm sure
>
// Just remember to either call a member function here or prefix
>
// all class access with self->
>
return result;
>
}
>
>
FInally I recommend only cleaning up the fGate at free time and no
>
earlier. A lot of tear down problems have been due to premature tear down
>
of the synchroniser.
>
>
free()
>
{
>
if (fGate)
>
{
>
IOWorkLoop *wl = fGate->getWorkLoop();
>
if (wl)
>
wl->removeEventSource(fGate);
>
fGate->release();
>
fGate = 0;
>
}
>
}
>
>
Godfrey
>
>
At 8:20 -0700 02-6-28, Scott Taggart wrote:
>
>Hi,
>
>
>
>I have two kexts: kext A is a USB driver sub-classed from IOService and
>
>Kext B sub-classed from IOEthernetController. B "calls" into "A" at
>
>various times to perform functions such as delivering outbound frames. I
>
>want to "lock" B from entering into A if A has already been entered (via
>
>USB callback, timer, etc.) (i.e., its "gate/lock" is busy). Can someone
>
>please give me the basics of how I make a given function entry point into
>
>A and have it play the "IO Gate" game (i.e., to make sure it's the only
>
>one with the lock). Function calls and a pointer to some sample code
>
>would be a big help.
>
>
>
>Thanks,
>
>
>
>Scott
_______________________________________________
darwin-kernel mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.