EmergMem.h

/*
    File:       EmergMem.h
 
    Contains:   EmergMem contains routines to handle emergency memory situations.  This is
                used for Toolbox routines that either donÕt check for memory-full errors, or
                that call _SysErr when they canÕt allocate the memory that they need.  The
                purpose of the routines in this file is to make sure that these toolbox
                routines always have the memory they need.
 
    Written by:  Forrest Tanaka 
 
    Copyright:  Copyright © 1988-1999 by Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
    Change History (most recent first):
                7/13/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/
#ifndef __EMERGMEM__
#define __EMERGMEM__
 
/******************************************************************************\
* Header Files
\******************************************************************************/
 
#include <Types.h>
#include <Memory.h>
 
 
/******************************************************************************\
* Constants
\******************************************************************************/
 
#define kAllocApp true /* For NewPtrMargin/NewHandleMargin for app heap alloc */
#define kAllocClr true /* For NewPtrMargin/NewHandleMargin to clear mem block */
 
 
/******************************************************************************\
* InstallAppGZ - Installs the application grow zone proc
*
* This routine is called whenever this applicationÕs simple grow-zone procedure
* (see EmergMem.c for the source for the grow-zone procedure) is to be
* installed.  From this point on, any requests for memory by this application or
* the system invoke our grow-zone procedure if there isnÕt enough memory to
* satisfy the request.
\******************************************************************************/
 
void InstallAppGZ(void);
 
 
/******************************************************************************\
* DeinstallAppGZ - install the application grow zone proc
*
* This routine is called whenever this applicationÕs simple grow-zone procedure
* (see EmergMem.c for the source for the grow-zone procedure) is to be
* deinstalled.  From this point on, any requests for memory by this application
* or the system return memFullErr if there isnÕt enough memory to satisfy the
* request.
\******************************************************************************/
 
void DeinstallAppGZ(void);
 
 
/******************************************************************************\
* InitEmergMem - Allocate emergency memory
*
* This is called at startup time to allocate the emergency memory block that can
* be deallocated by the grow zone procedure (this applicationÕs grow-zone
* procedure is defined privately in EmergMem.c).  InitEmergMem also installs
* this applicationÕs grow-zone proc.
*
* If there isnÕt enough memory to allocate the block of emergency memory, then
* a subsequent call to FailLowMemory(0) returns TRUE.
\******************************************************************************/
 
void InitEmergMem(void);
 
 
/******************************************************************************\
* RecoverEmergMem - Recover emergency memory
*
* This is called from the event loop if NoEmergMem indicates that the emergency
* memory was deallocated by this applicationÕs grow-zone procedure.  This
* routine will attempt recover the emergency memory.  If this fails, then some
* application options and commands are disabled until there is enough free
* memory to enable them again.
\******************************************************************************/
 
void RecoverEmergMem(void);
 
 
/******************************************************************************\
* FailLowMemory - Is there enough free space in heap to allocate memory?
*
* FailLowMemory is called any time a potentially significant amount of non-
* temporary memory is about to be allocated.  It returns true if thereÕs enough
* free space in the heap to allocate the requested amount of memory and still
* have a significant amount of free space left over, and if the emergency memory
* isnÕt being used.  See EmergMem.c for the definition of Òsignificant amount.Ó
* "memRequest" specifies the number of bytes that are about to be allocated.
*
* This routine is also used even if the exact amount of memory about to be
* allocated isnÕt known.  In this case, zero is passed in memRequest.  If
* FailLowMemory returns true, then thereÕs enough memory for the the emergency
* memory and a significant amount of free memory.  If FailLowMemory returns
* false, then either there isnÕt a significant amount of free memory, or if the
* emergency memory was deallocated by this applicationÕs grow-zone procedure, or
* both.  This is actually the usual way that I use this function, because I
* normally use it for calls to the Toolbox, and thereÕs usually no reliable way
* to determine how much memory the Toolbox is going to allocate.
\******************************************************************************/
 
Boolean FailLowMemory(
    long memRequest);
 
 
/******************************************************************************\
* NoEmergMem - Check to see if emergency memory is being used or not
*
* Before my application attempts to use more memory, I call this routine to
* check if I'm already using my emergency memory.  If so, then IÕd better
* prepare to die or get my emergency memory back.
\******************************************************************************/
 
Boolean NoEmergMem(void);
 
 
/******************************************************************************\
* NewHandleMargin - Create a new handle without using emergency memory
*
* Many toolbox routines simply call SysErr when they run out of memory.  ThatÕs
* not too cool, so I try to make certain that the memory they need is always
* available by making sure that I never request so much memory that the toolbox
* routines are in danger of running out of memory and calling SysErr.  This is
* achieved by calling NewHandleMargin instead of NewHandle any time a
* relocatable memory block is desired.  NewHandle returns memFullErr in MemErr
* if there isnÕt enough free contiguous space to satisfy the request.
* NewHandleMargin returns nil if there isnÕt enough memory to allocate a block
* of the size specified by "requestedSize".
*
*     WARNING: DonÕt depend on MemError after calling NewHandleMargin.  The
*     only way to tell whether it succeeded or not is to compare the result
*     against NIL.
*
* If "appHeapAlloc" is kAppHeap, then the block of memory is allocated in the
* applicationÕs heap.  If "appHeapAlloc" is !kAppHeap, then the block of
* memory is allocated in the system heap.
*
* If "clearMem" is kAllocClr, then all the bytes in the block of memory are
* cleared to zero.  If !kAllocClr is passed, then none of the bytes in the
* block of memory are touched after being allocated.
\******************************************************************************/
 
Handle NewHandleMargin(
    Size    requestedSize,
    Boolean appHeapAlloc,
    Boolean clearMem);
 
 
/******************************************************************************\
* NewPtrMargin - Create a new pointer without using emergency memory
*
* Many toolbox routines simply call SysErr when they run out of memory.  ThatÕs
* not too cool, so I try to make certain that the memory they need is always
* available by making sure that I never request so much memory that the toolbox
* routines are in danger of running out of memory and calling SysErr.  This is
* achieved by calling NewPtrMargin instead of NewPtr any time a non-relocatable
* memory block is desired.  NewPtr returns memFullErr in MemErr if there isnÕt
* enough free contiguous space to satisfy the request.  NewPtrMargin returns nil
* if there isnÕt enough memory to allocated a block of the size specified by
* "requestedSize".
*
*     WARNING: DonÕt depend on MemError after calling NewPtrMargin.  The
*     only way to tell whether it succeeded or not is to compare the result
*     against NIL.
*
* If "appHeapAlloc" is kAppHeap, then the block of memory is allocated in the
* applicationÕs heap.  If "appHeapAlloc" is !kAppHeap, then the block of
* memory is allocated in the system heap.
*
* If "clearMem" is kAllocClr, then all the bytes in the block of memory are
* cleared to zero.  If !kAllocClr is passed, then none of the bytes in the
* block of memory are touched after being allocated.
\******************************************************************************/
 
Ptr NewPtrMargin(
    Size    requestedSize,
    Boolean appHeapAlloc,
    Boolean clearMem);
 
 
#endif