Re: Two Kext Locking Question
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 | darwin-kernel@lists.apple.com Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-kernel Do not post admin requests to the list. They will be ignored.
participants (1)
-
Scott Taggart