5-DEC-20:17 Disk Font System BUG! From: PARISEAU To: ALL TITLE:Disk Font System BUG! There is a bug in the V1.0 and V1.1 diskfont.library code that can cause the system to crash when memory gets low. A workaround is presented below. Disk based system resources such as fonts and device drivers are brought in to memory when they are first opened. They remain in memory thereafter until some task asks for more memory than is available in the system free memory pool. At that point the EXEC function AllocMem() "expunges" (removes from memory) any such resources which currently have zero openers. This design means that resources tend to hang around in memory so that if they are frequently opened and closed there is no time lost reloading them from the disk. Many applications periodically use the trick of attempting to AllocMem() more memory than can possibly be in the system to flush any unused resources from memory. Note that if AllocMem() finds any resources to expunge, then the number returned by AvailMem() AFTER the call to AllocMem() will be larger than before the call (presuming of course that the AllocMem() does not, in fact, return a newly allocated chunk of memory to you). The bug is that when a disk based font is expunged from memory, the expunge code in diskfont.library does not properly remove the font descriptor from the list of fonts known to be in memory. Thereafter, whenever a font is looked-up, there is a chance that the system will crash since the font node now points at memory that has been returned to the system free pool. The workaround involves manually removing the font from the font list before you close it. The workaround, as presented, provides maximum protection for the system at the expense of possibly having multiple copies of the font temporarily exist in memory together. If you know that ALL font users in the system are using the workaround, then only the last closer of the font need do the Remove() function. Note that the V1.1 version of Notepad (for instance) does NOT implement this workaround. The workaround for the diskfont.library bug is, whenever closing a font: 1) Forbid(); 2) check the font flags to see if it is a disk font 3) if a disk font, check that this font is in a list by ensuring that the predecessor's and successor's nodes point to it. 4) if the font is in a list, Remove(0, font) it. 5) Permit(); 6) CloseFont(); Note that the first argument to Remove(), the 0, is a dummy argument present for historical purposes. The TextFont structure is described in the include file text.h (or text.i if you speak assembly). Note that the Accessors field contains the opener count for a font. If you are not concerned with reclaiming the memory space taken up by your unused fonts, it is sufficient, as an alternate workaround, simply to never close your fonts. This will insure that AllocMem() never tries to expunge the font. Note that this would keep the font from EVER going away -- even after your program terminates. If Notepad, or another program, has opened and closed disk fonts prior to the running of your program, the font list has the potential of being messed up the next time AllocMem() goes to expunge resources. If such an expunge has already occurred, there is no recovery other than to reboot the system. On the other hand, if an expunge has NOT yet occurred, you can protect yourself by emptying the font list before you first trigger an expunge. To empty the font list, traverse it starting from the TextFonts pointer found in the structure GfxBase. Do a Remove() on each disk based font in the list (WARNING! Only Remove() disk based fonts). The elements of the list are structures of the type TextFont. Note that you MUST do this cleanup prior to triggering your first expunge (i.e., before calling AllocMem() with a large value). This cleanup should be done while tasking is disabled (i.e., between a Forbid() and a Permit()). This bug will be fixed in the V1.2 system software. Any application implementing the above workaround will continue to work under the new system software.