home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Storage / Bento / SessHdr.cpp < prev    next >
Encoding:
Text File  |  1996-04-22  |  9.0 KB  |  361 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        SessHdr.cpp
  3.  
  4.     Contains:    Implementation of sessionRoutinesMetahandler and its
  5.                         associated handlers.
  6.  
  7.     Owned by:    David McCusker
  8.  
  9.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13.          <2>     3/29/96    DM        1296171: add booleans and ODBentoFatal-
  14.                                     Error() to process fatal container errors
  15.                                     through private API which shows a quitting
  16.                                     alert and exits to shell.
  17.          <6>    10/24/95    jpa        1293441: DM: Bento memory reserve.
  18.          <5>    10/20/95    VL        1293256: THROW kODBentoErr for all Bento
  19.                                     errors.
  20.          <4>     5/26/95    VL        1251403: Multithreading naming support.
  21.          <3>     6/20/94    CC        ODMemoryHeap* changed to ODMemoryHeapID.
  22.          <2>     6/15/94    RR        ODHeap -> ODMemoryHeap
  23.          <1>     5/27/94    VL        first checked in
  24.  
  25.     To Do:
  26.     In Progress:
  27.         
  28. */
  29.  
  30. //==============================================================================
  31. // Theory of Operation
  32. //==============================================================================
  33.  
  34. /*
  35.  
  36.     This file contains a fully documented example of the set of session handlers and its
  37.     metahandler as it would be used by the Container Manager CMStartSession() routine.
  38.  
  39.     When you call CMStartSession() you pass a pointer to a metahandler that is used to get
  40.     the addresses of the error reporting, memory allocator and memory deallocator routines.
  41.     Possibly others might be defined in the future.
  42.     
  43. */
  44.  
  45. #ifndef _SESSHDR_
  46. #include "SessHdr.h"
  47. #endif
  48.  
  49. #ifndef _ODDEBUG_
  50. #include "ODDebug.h"
  51. #endif
  52.  
  53. #ifndef _USERSRCM_
  54. #include "UseRsrcM.h"
  55. #endif
  56.  
  57. #ifndef _DLOGUTIL_
  58. #include "DlogUtil.h"
  59. #endif
  60.  
  61. #ifndef _EXCEPT_
  62. #include "Except.h"
  63. #endif
  64.  
  65. #ifndef __CM_API__
  66. #include "CMAPI.h"
  67. #endif
  68.  
  69. #ifndef _ODMEMORY_
  70. #include "ODMemory.h"
  71. #endif
  72.  
  73. #ifndef _PLFMDEF_
  74. #include "PlfmDef.h"
  75. #endif
  76.  
  77. #ifndef _BENTODEF_
  78. #include "BentoDef.h"
  79. #endif
  80.  
  81. #ifndef _MEMMGR_
  82. #include "MemMgr.h"
  83. #endif
  84.  
  85. #ifndef _STORRSRC_
  86. #include "StorRsrc.h"
  87. #endif
  88.  
  89. #include <stddef.h>
  90. #include <stdlib.h>
  91. #include <stdio.h>
  92. #include <string.h>
  93. #include <stdarg.h>
  94.  
  95. #pragma segment SessHdr
  96.  
  97. //==============================================================================
  98. // Function Prototype
  99. //==============================================================================
  100.  
  101.     CM_CFUNCTIONS
  102.     
  103.  CMHandlerAddr CM_FIXEDARGS sessionRoutinesMetahandler(CMType targetType, CMconst_CMGlobalName operationType);
  104.                                                                 
  105.  static void CM_VARARGS error_Handler(CMErrorNbr errorNumber, ...);
  106.  static void CM_PTR * CM_FIXEDARGS alloc_Handler(CMSize size, CMRefCon sessionRefCon);
  107.  static void CM_FIXEDARGS free_Handler(CMPtr ptr, CMRefCon sessionRefCon);
  108.                                                                  
  109.     CM_END_CFUNCTIONS
  110.  
  111. //------------------------------------------------------------------------------
  112. // sessionRoutinesMetahandler
  113. //------------------------------------------------------------------------------
  114. CMHandlerAddr CM_FIXEDARGS sessionRoutinesMetahandler( CMType targetType,
  115.                                                        CMconst_CMGlobalName operationType )
  116. {
  117.     static char *operationTypes[] = {CMErrorOpType,                    /*  0 */ /*  Operation Types    */
  118.                                      CMAllocOpType,                    /*  1 */
  119.                                      CMFreeOpType,                    /*  2 */
  120.                                      NULL};
  121.     char      **t;
  122.     CMType ignored = targetType;
  123.     
  124.     /* Look up the operation type in the operationTypes table above...                                */
  125.     
  126.     t = operationTypes - 1;
  127.     while (*++t) if (strcmp((char *)operationType, *t) == 0) break;
  128.  
  129.     /* Now that we got it (hopefully), return the appropriate routine address...                    */
  130.     
  131.     switch (t - operationTypes) {
  132.         case  0:    return ((CMHandlerAddr)error_Handler);                        /* CMErrorOpType                 */
  133.         case  1:    return ((CMHandlerAddr)alloc_Handler);                        /* CMAllocOpType                 */
  134.         case  2:    return ((CMHandlerAddr)free_Handler);                        /* CMFreeOpType                 */
  135.         
  136.         default:    return (NULL);                                                /* huh?                            */
  137.     }
  138. }
  139.  
  140. //------------------------------------------------------------------------------
  141. // ODBentoFatalError
  142. //------------------------------------------------------------------------------
  143.  
  144. #if ODDebug
  145. void BREAK( const char[] );
  146. #endif
  147.  
  148. ODBoolean gODBentoFatalErrorHasOccurred = kODFalse;
  149. ODBoolean gODDelayBentoFatalError = kODFalse;
  150. ODBoolean gODSuppressBentoFatalError = kODFalse;
  151.  
  152. void ODBentoFatalError(); // prototype
  153.  
  154. void ODBentoFatalError()
  155. {
  156.     if ( !gODSuppressBentoFatalError )
  157.     {
  158.         gODBentoFatalErrorHasOccurred = kODTrue;
  159.  
  160.         if ( gODDelayBentoFatalError )
  161.         {
  162. #if ODDebug
  163.             BREAK("fatal container error delayed, continuing...");
  164. #endif
  165.         }
  166.         else
  167.         {
  168. #if ODDebug
  169.             BREAK("about to show fatal Bento error alert...");
  170. #endif
  171.             {
  172.                 TRY{
  173.                     CUsingLibraryResources r;
  174.                     InitCursor();
  175.                     ::Alert(kODAlertFatalContainerError, kODNULL);
  176.                 }CATCH_ALL{
  177.                     WARN("cannot show fatal Bento err alert - quitting...");
  178.                 }ENDTRY
  179.             }
  180.             // make sure CUsingLibraryResources goes out of scope first...
  181.             ::ExitToShell(); // bye bye process
  182.         }
  183.     }
  184.     else
  185.     {
  186.         // Do not break here because it is really annoying when
  187.         // suppressing errors associated with IsValidStorageUnitRef():
  188.         
  189. //#if ODDebug
  190. //        BREAK("clipboard Bento error is non-fatal ...");
  191. //#endif
  192.     }
  193. }
  194.  
  195. //------------------------------------------------------------------------------
  196. // error_Handler
  197. //------------------------------------------------------------------------------
  198.  
  199. static void CM_VARARGS error_Handler(CMErrorNbr errorNumber, ...)
  200. {
  201.     va_list inserts;
  202.     char errorString[256];
  203.  
  204.     va_start(inserts, errorNumber);
  205.     CMVGetErrorString(errorString, 256, errorNumber, inserts);
  206.     va_end(inserts);
  207.  
  208.     ODBentoFatalError();
  209.     THROW(kODErrBentoErr, errorString);
  210. }
  211.  
  212. //------------------------------------------------------------------------------
  213. // ODSession_Trace
  214. //------------------------------------------------------------------------------
  215.  
  216. #ifdef ODDebugBentoSize
  217. static void ODSession_Trace(ODSessionRefCon* session, long size)
  218. {
  219.     ODBoolean reverse = (session->fUp && size < 0) || (!session->fUp && size > 0);
  220.     ODULong oldTotal = session->fTotal;
  221.     
  222.     if ( size < 0 ) // freeing
  223.     {
  224.         if (reverse) // previous total was a local high
  225.             session->fHigh = session->fTotal;
  226.  
  227.         session->fUp = kODFalse;
  228.         long amount = -size;
  229.         if (session->fTotal < amount)
  230.             session->fTotal = amount;
  231.         else
  232.             session->fTotal -= amount;
  233.             
  234.     }
  235.     else //allocating
  236.     {
  237.         if (reverse) // previous total was a local low
  238.             session->fLow = session->fTotal;
  239.  
  240.         session->fUp = kODTrue;
  241.         session->fTotal += size;
  242.     }
  243.     
  244.     if (session->fTotal > session->fHighest)
  245.         session->fHighest = session->fTotal;
  246.     
  247.     long diff = ((long) session->fTotal - (long) session->fMark);
  248.     ODBoolean mark = (diff > 2048 || diff < -2048);
  249.     if (mark)
  250.         session->fMark = session->fTotal;
  251.         
  252.     if (reverse || mark)
  253.     {
  254.         if ( session->fUp )
  255.             somPrintf("•alloc•(%ld) [%lu] : %lu UP FROM %lu\n", 
  256.                 size,  session->fHighest, session->fTotal, session->fLow);
  257.         else
  258.             somPrintf("•free•(%ld) [%lu] : %lu down from %lu\n", 
  259.                 size,  session->fHighest, session->fTotal, session->fHigh);        
  260.     }
  261.     else
  262.     {
  263.         if ( session->fUp )
  264.             somPrintf("/ %ld \\\n", size);
  265.         else 
  266.             somPrintf("\\ %ld /\n", size);
  267.     }
  268. }
  269. #endif
  270.  
  271. //------------------------------------------------------------------------------
  272. // alloc_Handler
  273. //------------------------------------------------------------------------------
  274.  
  275. static void CM_PTR * CM_FIXEDARGS alloc_Handler(CMSize size, CMRefCon sessionRefCon)
  276. {
  277.     ODMemoryHeapID        heap = kDefaultHeapID;
  278.     ODSessionRefCon* sessRc = (ODSessionRefCon*) sessionRefCon;
  279.     
  280.     if (sessionRefCon != kODNULL)
  281.         heap = sessRc->heap;
  282.  
  283.     void* block = MMAllocate(size);
  284.     if ( !block )
  285.     {
  286.         if ( sessRc->cmAllocReserveBlock )
  287.         {
  288.             void* reserve = sessRc->cmAllocReserveBlock;
  289.             sessRc->cmAllocReserveBlock = kODNULL;
  290.             
  291.             MMFree(reserve);
  292.             block = MMAllocate(size);
  293.         }
  294.     }
  295.     if ( !block )
  296.         THROW( kODErrOutOfMemory ); // should be kFatalError
  297.  
  298. #ifdef ODDebugBentoSize
  299.     long blockSize = (long) MMBlockSize(block) + 8;
  300.         
  301.     ODSession_Trace(sessRc, (long) blockSize); 
  302.  
  303.     return block;
  304. #else
  305.  
  306.     // return ODNewPtr(size, heap);
  307.     return block;
  308. #endif
  309.         
  310. }
  311.  
  312. //------------------------------------------------------------------------------
  313. // free_Handler
  314. //------------------------------------------------------------------------------
  315.  
  316.  
  317. static void CM_FIXEDARGS free_Handler(CMPtr ptr, CMRefCon sessionRefCon)
  318. {
  319.  
  320. #ifdef ODDebugBentoSize
  321.     if ( ptr )
  322.     {
  323.         long blockSize = (long) MMBlockSize(ptr) + 8;
  324.         ODSession_Trace((ODSessionRefCon*) sessionRefCon,  - blockSize ); 
  325.     }
  326. #else
  327. ODUnused(sessionRefCon);
  328. #endif
  329.  
  330.     ODDisposePtr(ptr);
  331. }
  332.  
  333. //------------------------------------------------------------------------------
  334. // reserve
  335. //------------------------------------------------------------------------------
  336.  
  337.  
  338. // void*            cmAllocReserveBlock;
  339. // CMSize           cmAllocReserveSize;
  340.  
  341. void ODSessionMustHaveCMAllocReserve(CMContainer cmContainer)
  342. {
  343.     if (cmContainer)
  344.     {
  345.         ODSessionRefCon* src = (ODSessionRefCon*) CMGetSessionRefCon(cmContainer);
  346.         if ( src && !src->cmAllocReserveBlock )
  347.             src->cmAllocReserveBlock = ODNewPtr(src->cmAllocReserveSize, src->heap);
  348.     }
  349. }
  350.  
  351. void ODSessionRestoreCMAllocReserve(CMContainer cmContainer)
  352. {
  353.     if (cmContainer)
  354.     {
  355.         ODSessionRefCon* src = (ODSessionRefCon*) CMGetSessionRefCon(cmContainer);
  356.         if ( src && !src->cmAllocReserveBlock )
  357.             src->cmAllocReserveBlock = MMAllocate( src->cmAllocReserveSize );
  358.     }
  359. }
  360.  
  361.