Previous Next Contents

7. Annex

7.1 Environment variables used by MacCVS/WinCVS

Most the communication of MacCVS & WinCVS with cvs is done thru environment variables.

The cvs documentation will tell you about these variables. We'll refer here only to the most used ones or to the one only used by WinCVS/MacCVS.

The reason you may want to be aware of this variables is because you want to use the AppleEvent capability of MacCVS or the MPW tools.

Mac Note : Some of the variables are noted as "globals" : it means that if you do not define it, the MPW tool or MacCVS by AppleEvent will get these values directly from the MacCVS preferences. So you don't need to define them, unless you want to overide these values.

7.2 A discussion about MacCVS architecture and the CR/LF problem

email of Miro Jurisic to Alexandre Parenteau

I think it's very important that you know what was going on, so I'll write a hopefully clear description here... if you have any questions please ask :)

Now that we got those clearly written, let's see what the cvsLib glue does:

cvsLib has its own WriteCharsToConsole which calls into MacCVS. This is setup when the library is loaded (in function loadCVS). Specifically, cvsLib's WriteCharsToConsole calls MacCVS' consoleout. consoleout does one of two things: if MacCVS is being run via AppleEvents, it writes output to the reply event. Otherwise, if calls fwrite on stdout to write the data to the console.

Okay, so the way that the 3.0b3 code works is like this:

Hopefully, now you see where the problem is (this is where I was late Monday afternoon).

I decided that it was not necessary to go through the process of loading and unloading cvsLib all the time (I was not aware of the problems that would cause), so I rearranged the libraries between fragments. I fixed the \n\r problem, but I introduced a new problem: cvs was crashing reproducibly the _second_ time a cvs command was invoked. This is where I went to bed on Monday.

On Tuesday, I woke up and started stepping through the code to determine why the garbage collector is blowing up. I traced the problem to some globals being freed twice. What was going on? Since I changed the linkage so that cvsLib was only loaded once, its globals were initialized when MacCVS was started up. The first time cvsLib was called, it allocated space for some strings and set some globals to point to them. Before returning it freed those globals - but it didn't set them to NULL after freeing them. The second time cvsLib was invoked, some of those globals were freed again (because they weren't NULL), which was wrong.

At that point I realized that the library must be loaded and unloaded repeatedly; I also got your email in which you said that GUSI should be loaded and unloaded repeatedly because it contains those static destructors that clean up MacTCP state.

After reading that I stepped away from my computer, went to the drawing board, and concluded that it is impossible to do anything but to have a closer look at the cvsLib glue, and see whether the hidden conversion can be eliminated. This turned out to be far simpler that I could hope for: instead of calling fwrite from consoleout, I called directly WriteCharsToConsole, thereby avoiding the extra conversing that was the problem. Of course, I also had to turn 'Map newline to CR' in the settings, to even everything out. The result is that:

Whew!

Please let me know if you are unclear on this... now I have a good view of the problem and how I fixed it, and some really great insight on how pieces of MacCVS fit together.

...

cheers,

meeroh


Previous Next Contents