home *** CD-ROM | disk | FTP | other *** search
- /* LibHandler.c
-
- Copyright 1993 by Christopher A. Wichura (caw@miroc.chi.il.us)
- All Rights Reserved.
- */
-
- struct SignalSemaphore HandleListSema;
- struct MinList HandleList;
-
- /*
- * we need to serialize people calling our Open and Close routines so use
- * another semaphore for that
- */
- static struct SignalSemaphore OpenCloseSema;
-
- /* pointers to a couple of librarys we open */
- struct DosLibrary *DOSBase;
- struct Library *UtilityBase;
- struct Library *OwnDevUnitBase;
-
- /* pointer to SysBase used by the rest of the system */
- struct ExecBase *SysBase;
-
- APTR pool;
- struct SignalSemaphore poolSema;
-
- struct MyLibrary {
- struct Library ml_Lib;
- BPTR ml_SegList;
- };
-
- /***************************************************************************/
- /***************************************************************************/
- /** These are the library base routines used to open/close us, etc **/
- /***************************************************************************/
- /***************************************************************************/
-
- struct MyLibrary *__saveds __asm LibInit(register __d0 struct MyLibrary *LibBase, register __a0 BPTR LibSegment)
- {
- SysBase = *(struct ExecBase **)4L;
- LibBase->ml_SegList = LibSegment;
-
- NewList((struct List *)&HandleList);
- InitSemaphore(&HandleListSema);
-
- InitSemaphore(&OpenCloseSema);
-
- InitSemaphore(&poolSema);
-
- #define POOLSIZE (4096)
- if (!(pool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR, POOLSIZE, POOLSIZE / 2))) {
- Alert(AT_Recovery | AG_NoMemory);
- return 0L;
- }
-
- return LibBase;
- }
-
- ULONG __saveds __asm LibExpunge(register __a6 struct MyLibrary *LibraryBase)
- {
- BOOL KillLib;
- LONG LibSize;
- BPTR LibrarySeg;
-
- KillLib = FALSE;
-
- /*
- * we will refuse to expunge if we are currently tracking devices,
- * regardless of our OpenCnt. We AttemptSemaphore() the HandleList
- * before checking it. If someone else owns it then obviously we
- * can't try to shut down.
- */
-
- if (LibraryBase->ml_Lib.lib_OpenCnt == 0 && AttemptSemaphore(&HandleListSema)) {
- if (HandleList.mlh_TailPred == (struct MinNode *)&HandleList.mlh_Head) {
- Remove((struct Node *)LibraryBase);
- KillLib = TRUE;
- }
-
- ReleaseSemaphore(&HandleListSema);
- }
-
- if (KillLib) {
- DeletePool(pool);
-
- LibrarySeg = LibraryBase->ml_SegList;
- LibSize = LibraryBase->ml_Lib.lib_NegSize + LibraryBase->ml_Lib.lib_PosSize;
- FreeMem((char *)LibraryBase - LibraryBase->ml_Lib.lib_NegSize, LibSize);
-
- return (ULONG)LibrarySeg;
- }
-
- LibraryBase->ml_Lib.lib_Flags |= LIBF_DELEXP;
- return (ULONG)NULL;
- }
-
- struct MyLibrary *__saveds __asm LibOpen(register __a6 struct MyLibrary *LibraryBase)
- {
- ObtainSemaphore(&OpenCloseSema);
-
- if (++LibraryBase->ml_Lib.lib_OpenCnt == 1) {
- /* when opencount = 1 then we need to open libraries */
- if (DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)) {
- if (UtilityBase = OpenLibrary("utility.library", 37)) {
-
- /*
- * note that we really do care if we can open
- * ODU or not. This is because ODU is the
- * principal mechanism used by the lock
- * routines and if ODU isn't around then we
- * can't insure that we have really locked a
- * file and could potentially run into
- * problems.
- */
-
- if (OwnDevUnitBase = OpenLibrary(ODU_NAME, 0)) {
-
- /*
- * we have opened everything we need
- * successfully so clear the delayed
- * expunge flag and return
- * LibraryBase to indicate that the
- * library opened ok.
- */
-
- LibraryBase->ml_Lib.lib_Flags &= ~LIBF_DELEXP;
- ReleaseSemaphore(&OpenCloseSema);
- return LibraryBase;
- }
- else
- Alert(AT_Recovery | AG_OpenLib | AO_Unknown);
-
- CloseLibrary(UtilityBase);
- UtilityBase = NULL;
- }
- else
- Alert(AT_Recovery | AG_OpenLib | AO_UtilityLib);
-
- CloseLibrary((struct Library *)DOSBase);
- DOSBase = NULL;
- }
- else
- Alert(AT_Recovery | AG_OpenLib | AO_DOSLib);
-
- ReleaseSemaphore(&OpenCloseSema);
- return (struct MyLibrary *)NULL;
- }
-
- LibraryBase->ml_Lib.lib_Flags &= ~LIBF_DELEXP;
- ReleaseSemaphore(&OpenCloseSema);
- return LibraryBase;
- }
-
- ULONG __saveds __asm LibClose(register __a6 struct MyLibrary *LibraryBase)
- {
- BOOL DoExpunge = FALSE;
-
- ObtainSemaphore(&OpenCloseSema);
-
- if (--LibraryBase->ml_Lib.lib_OpenCnt == 0) {
- CloseLibrary(OwnDevUnitBase); /* relies on KS 2.0+ allowing
- * one to call CloseLibrary()
- * with a NULL base. If
- * making a library for user
- * under 1.3 (ugh!) make sure
- * that closing of library
- * bases which are not
- * mandatory have checks to
- * make sure they are not
- * NULL before calling
- * CloseLibrary(). */
- OwnDevUnitBase = NULL;
- CloseLibrary(UtilityBase);
- UtilityBase = NULL;
- CloseLibrary((struct Library *)DOSBase);
- DOSBase = NULL;
-
- if (LibraryBase->ml_Lib.lib_Flags & LIBF_DELEXP) {
- DoExpunge = TRUE;
- }
- }
-
- ReleaseSemaphore(&OpenCloseSema);
-
- if (DoExpunge)
- return LibExpunge(LibraryBase);
- else
- return (ULONG)NULL;
- }
-