3-11-02

I still believe I know what to do in theory, but have run into some problems on implementation. Here's the scoop, at least as far as I know:

The problem is basically a race condition that occurs with some calls in CarbonEventLib and when a program using CarbonLib does an ExitToShell, which eventually releases CarbonLib from memory. The particular culprit I have seen looks like a call from within Carbon's version of WaitNextEvent ("RealWNE") to Carbon's version of FlushEvents ("RealFlushEvents") that appears to have been blocked somewhere (this is probably where the FireWire dependency comes in although I haven't figured out how), and before the code gets unblocked or resumes, the ExitToShell executes or completes releasing CarbonLib from memory so when the code tries to return, it dies.

The real fix would be to make Carbon (or the system if it's an interaction between Carbon and the system) block the exit code until the call the RealFlushEvents returns and additionally prevent any future calls like that from occuring. There is unlikely to be a patchable solution w/o source code for CarbonLib, however (I don't think I can do this from the current Carbon SDK, but I haven't checked for sure; besides at the moment I don't have a current version of CodeWarrior). This is why the problem happens after the "last" problem application quits; the other apps hold CarbonLib in core until that last one exits. I tried patching CarbonLib's INIT code to permanently keep the CarbonEventLib fragment (only a small part of CarbonLib) loaded, but unfortunately that just
moves the problem since CarbonEventLib appears to go to other places in Carbon that were still gone at this point.

So, since memory is cheap, my idea is to load CarbonLib permanently (assuming you load it at all); basically I am keeping an "always open" application. However, I haven't been able to get this to work yet. Carbon as a whole is complex enough and has dependencies on the ProcessManager so that patching this to work at INIT time causes a crash trying to do something that I've not thought was a
profitable thing to try and fix by fixing the crash. Since the code I currently have is 68K and I don't have a good PPC disassembly patcher (remember what I said earlier about CodeWarrior), I tried hacking a simple old 68K app to do this for me (with the hopes of turning it into an appe, or at least verifying that this theory is still viable), but it Carbon failed to load for it siting a rather unuseful failure of one of the fragment initiailization routines.

What would probably work the best would be to patch the Finder, but the Finder is all PPC code in the data fork which is much more difficult for me to work with. Note that CarbonLib 1.0.4 or older doesn't have CarbonEvents, so I will guess that it won't show the problem. I haven't tried this because I think it's likely that Carbon that old won't run in some of the apps of interest anyway, but someone may wish to try this.

The possible workarounds I now see are: (1) remove carbon or FireWire
(2) keep one of those apps always open (but that will lead to a crash at
shutdown, in all liklihood) (3) use CarbonLib 1.0.4 or older
(unverified).

-kby