home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / comm / cyberpager-1.5.lha / CyberPager / source / library / LibHandler.c < prev    next >
C/C++ Source or Header  |  1994-02-07  |  5KB  |  190 lines

  1. /* LibHandler.c
  2.  
  3.    Copyright 1993 by Christopher A. Wichura (caw@miroc.chi.il.us)
  4.    All Rights Reserved.
  5. */
  6.  
  7. struct SignalSemaphore HandleListSema;
  8. struct MinList HandleList;
  9.  
  10.  /*
  11.   * we need to serialize people calling our Open and Close routines so use
  12.   * another semaphore for that
  13.   */
  14. static struct SignalSemaphore OpenCloseSema;
  15.  
  16.  /* pointers to a couple of librarys we open */
  17. struct DosLibrary *DOSBase;
  18. struct Library *UtilityBase;
  19. struct Library *OwnDevUnitBase;
  20.  
  21.  /* pointer to SysBase used by the rest of the system */
  22. struct ExecBase *SysBase;
  23.  
  24. APTR pool;
  25. struct SignalSemaphore poolSema;
  26.  
  27.   struct MyLibrary {
  28.       struct Library ml_Lib;
  29.       BPTR ml_SegList;
  30.   };
  31.  
  32. /***************************************************************************/
  33. /***************************************************************************/
  34. /**     These are the library base routines used to open/close us, etc    **/
  35. /***************************************************************************/
  36. /***************************************************************************/
  37.  
  38. struct MyLibrary *__saveds __asm LibInit(register __d0 struct MyLibrary *LibBase, register __a0 BPTR LibSegment)
  39. {
  40.     SysBase = *(struct ExecBase **)4L;
  41.     LibBase->ml_SegList = LibSegment;
  42.  
  43.     NewList((struct List *)&HandleList);
  44.     InitSemaphore(&HandleListSema);
  45.  
  46.     InitSemaphore(&OpenCloseSema);
  47.  
  48.     InitSemaphore(&poolSema);
  49.  
  50. #define POOLSIZE (4096)
  51.     if (!(pool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR, POOLSIZE, POOLSIZE / 2))) {
  52.         Alert(AT_Recovery | AG_NoMemory);
  53.         return 0L;
  54.     }
  55.  
  56.     return LibBase;
  57. }
  58.  
  59. ULONG __saveds __asm LibExpunge(register __a6 struct MyLibrary *LibraryBase)
  60. {
  61.     BOOL KillLib;
  62.     LONG LibSize;
  63.     BPTR LibrarySeg;
  64.  
  65.     KillLib = FALSE;
  66.  
  67.     /*
  68.      * we will refuse to expunge if we are currently tracking devices,
  69.      * regardless of our OpenCnt.  We AttemptSemaphore() the HandleList
  70.      * before checking it.  If someone else owns it then obviously we
  71.      * can't try to shut down.
  72.      */
  73.  
  74.     if (LibraryBase->ml_Lib.lib_OpenCnt == 0 && AttemptSemaphore(&HandleListSema)) {
  75.         if (HandleList.mlh_TailPred == (struct MinNode *)&HandleList.mlh_Head) {
  76.             Remove((struct Node *)LibraryBase);
  77.             KillLib = TRUE;
  78.         }
  79.  
  80.         ReleaseSemaphore(&HandleListSema);
  81.     }
  82.  
  83.     if (KillLib) {
  84.         DeletePool(pool);
  85.  
  86.         LibrarySeg = LibraryBase->ml_SegList;
  87.         LibSize = LibraryBase->ml_Lib.lib_NegSize + LibraryBase->ml_Lib.lib_PosSize;
  88.         FreeMem((char *)LibraryBase - LibraryBase->ml_Lib.lib_NegSize, LibSize);
  89.  
  90.         return (ULONG)LibrarySeg;
  91.     }
  92.  
  93.     LibraryBase->ml_Lib.lib_Flags |= LIBF_DELEXP;
  94.     return (ULONG)NULL;
  95. }
  96.  
  97. struct MyLibrary *__saveds __asm LibOpen(register __a6 struct MyLibrary *LibraryBase)
  98. {
  99.     ObtainSemaphore(&OpenCloseSema);
  100.  
  101.     if (++LibraryBase->ml_Lib.lib_OpenCnt == 1) {
  102.         /* when opencount = 1 then we need to open libraries */
  103.         if (DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)) {
  104.             if (UtilityBase = OpenLibrary("utility.library", 37)) {
  105.  
  106.                 /*
  107.                  * note that we really do care if we can open
  108.                  * ODU or not.  This is because ODU is the
  109.                  * principal mechanism used by the lock
  110.                  * routines and if ODU isn't around then we
  111.                  * can't insure that we have really locked a
  112.                  * file and could potentially run into
  113.                  * problems.
  114.                  */
  115.  
  116.                 if (OwnDevUnitBase = OpenLibrary(ODU_NAME, 0)) {
  117.  
  118.                     /*
  119.                      * we have opened everything we need
  120.                      * successfully so clear the delayed
  121.                      * expunge flag and return
  122.                      * LibraryBase to indicate that the
  123.                      * library opened ok.
  124.                      */
  125.  
  126.                     LibraryBase->ml_Lib.lib_Flags &= ~LIBF_DELEXP;
  127.                     ReleaseSemaphore(&OpenCloseSema);
  128.                     return LibraryBase;
  129.                 }
  130.                 else
  131.                     Alert(AT_Recovery | AG_OpenLib | AO_Unknown);
  132.  
  133.                 CloseLibrary(UtilityBase);
  134.                 UtilityBase = NULL;
  135.             }
  136.             else
  137.                 Alert(AT_Recovery | AG_OpenLib | AO_UtilityLib);
  138.  
  139.             CloseLibrary((struct Library *)DOSBase);
  140.             DOSBase = NULL;
  141.         }
  142.         else
  143.             Alert(AT_Recovery | AG_OpenLib | AO_DOSLib);
  144.  
  145.         ReleaseSemaphore(&OpenCloseSema);
  146.         return (struct MyLibrary *)NULL;
  147.     }
  148.  
  149.     LibraryBase->ml_Lib.lib_Flags &= ~LIBF_DELEXP;
  150.     ReleaseSemaphore(&OpenCloseSema);
  151.     return LibraryBase;
  152. }
  153.  
  154. ULONG __saveds __asm LibClose(register __a6 struct MyLibrary *LibraryBase)
  155. {
  156.     BOOL DoExpunge = FALSE;
  157.  
  158.     ObtainSemaphore(&OpenCloseSema);
  159.  
  160.     if (--LibraryBase->ml_Lib.lib_OpenCnt == 0) {
  161.         CloseLibrary(OwnDevUnitBase);    /* relies on KS 2.0+ allowing
  162.                          * one to call CloseLibrary()
  163.                          * with a NULL base.  If
  164.                          * making a library for user
  165.                          * under 1.3 (ugh!) make sure
  166.                          * that closing of library
  167.                          * bases which are not
  168.                          * mandatory have checks to
  169.                          * make sure they are not
  170.                          * NULL before calling
  171.                          * CloseLibrary(). */
  172.         OwnDevUnitBase = NULL;
  173.         CloseLibrary(UtilityBase);
  174.         UtilityBase = NULL;
  175.         CloseLibrary((struct Library *)DOSBase);
  176.         DOSBase = NULL;
  177.  
  178.         if (LibraryBase->ml_Lib.lib_Flags & LIBF_DELEXP) {
  179.             DoExpunge = TRUE;
  180.         }
  181.     }
  182.  
  183.     ReleaseSemaphore(&OpenCloseSema);
  184.  
  185.     if (DoExpunge)
  186.         return LibExpunge(LibraryBase);
  187.     else
  188.         return (ULONG)NULL;
  189. }
  190.