home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / mm / fssht / shinit.c < prev    next >
C/C++ Source or Header  |  1999-05-11  |  18KB  |  416 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*                    Copyright (c) IBM Corporation 1992, 1993              */
  4. /*                           All Rights Reserved                            */
  5. /*                                                                          */
  6. /* SOURCE FILE NAME: SHINIT.C                                               */
  7. /*                                                                          */
  8. /* DESCRIPTIVE NAME:  Stream Handler Dll Initialization routine             */
  9. /*                                                                          */
  10. /* FUNCTION: This function is called each time a new process loads this     */
  11. /*           DLL.  If this is the first call, we must register with the     */
  12. /*           SSM as a handler.  For each call, we need to allocate any      */
  13. /*           resources needed on a process basis (GetSeg's, etc), and       */
  14. /*           set up an exit list routine to deallocate these resources.     */
  15. /*                                                                          */
  16. /* ENTRY POINTS:                                                            */
  17. /*   _DLL_InitTerm                                                          */
  18. /*   ShExitList                                                             */
  19. /*************************** END OF SPECIFICATIONS **************************/
  20.  
  21. #ifdef MMRAS
  22. #define MMRAS_PTRACE
  23. #endif
  24. #ifdef PTRACE
  25. #define MMRAS_PTRACE
  26. #endif
  27.  
  28. #define  INCL_NOPMAPI                  /* no PM include files required */
  29. #define  INCL_DOSSEMAPHORES
  30. #define  INCL_DOSPROCESS               /* For exit list defines        */
  31. #define  INCL_DOSERRORS
  32. #define  INCL_DOSMISC
  33. #define  INCL_DOSDEVICES
  34. #define  INCL_OS2MM
  35. #include <os2.h>
  36. #include <os2me.h>
  37. #include <hhpheap.h>
  38. #include <shi.h>
  39.  
  40. #ifdef MMRAS_PTRACE
  41. #include <ptrace.h>
  42. #endif
  43.  
  44.  
  45. /************************** START OF SPECIFICATIONS *************************/
  46. /*                                                                          */
  47. /* SUBROUTINE NAME: ShInit                                                  */
  48. /*                                                                          */
  49. /* DESCRIPTIVE NAME: Stream Handler Initialization routine                  */
  50. /*                                                                          */
  51. /* FUNCTION: DLL initialization routine, to set up control blocks, allocate */
  52. /*           storage etc.                                                   */
  53. /*                                                                          */
  54. /* NOTES:                                                                   */
  55. /*                                                                          */
  56. /* ENTRY POINT: _DLL_InitTerm                                               */
  57. /*   LINKAGE:   CALL NEAR (0:32)                                            */
  58. /*                                                                          */
  59. /* INPUT:                                                                   */
  60. /*   HMODULE hmod        Module handle                                      */
  61. /*   ULONG   fTerm       DLL termination flag                               */
  62. /*                                                                          */
  63. /* EXIT-NORMAL: NO_ERROR (0)                                                */
  64. /*                                                                          */
  65. /* EXIT-ERROR:                                                              */
  66. /*   ERROR_ALLOC_RESOURCES                                                  */
  67. /*                                                                          */
  68. /* SIDE EFFECTS:                                                            */
  69. /*                                                                          */
  70. /* INTERNAL REFERENCES:                                                     */
  71. /*        ROUTINES: None                                                    */
  72. /*                                                                          */
  73. /* EXTERNAL REFERENCES:                                                     */
  74. /*   ROUTINES:                                                              */
  75. /*     _CRT_init                                                            */
  76. /*     DosCreateMutexSem                                                    */
  77. /*     DosOpenMutexSem                                                      */
  78. /*     DosRequestMutexSem                                                   */
  79. /*     DosCloseMutexSem                                                     */
  80. /*     SMHEntryPoint                                                        */
  81. /*     HhpCreateHeap                                                        */
  82. /*     HhpAccessHeap                                                        */
  83. /*     DosExitList                                                          */
  84. /*     HhpReleaseHeap                                                       */
  85. /*     DosReleaseMutexSem                                                   */
  86. /*                                                                          */
  87. /*   DATA STRUCTURES:                                                       */
  88. /*     hmtxGlobalData                                                       */
  89. /*     hHeap                                                                */
  90. /*                                                                          */
  91. /*************************** END OF SPECIFICATIONS **************************/
  92. INT _CRT_init(VOID);
  93.  
  94. ULONG _DLL_InitTerm( HMODULE hmod, ULONG fTerm)
  95.  
  96. { /* Start of ShInit */
  97.  
  98. RC rc = NO_ERROR;                       /* local return code */
  99. PARM_REG smhRegParm;                    /* Parameters for SMH_REGISTER */
  100. int Registered = FALSE;
  101. int HeapAllocated_Attached = FALSE;
  102. int GlobDataMtxCreated = FALSE;
  103. hmod;
  104.  
  105.   /*
  106.    * Checking this parameter will insure that this routine will only
  107.    * be run on an actual initialization.  Return success from the
  108.    * termination.
  109.    */
  110.  
  111.   if (fTerm)
  112.      {
  113.      return (1L);
  114.      }
  115.  
  116.   if (_CRT_init())
  117.      {
  118.      return (0L);
  119.      }
  120.  
  121.   /*
  122.    * Get the semaphore controlling the process count & update the process
  123.    * count if successful.  Then after we have the sem, if the count is
  124.    * one, we are guaranteed that we must do the global initializations.
  125.    *
  126.    * There is a problem that to determine if we need to create or open the
  127.    * semaphore we need to check the ProcessCount to see if this is the
  128.    * first process, but since we don't have the semaphore we don't have
  129.    * a guarentee the count won't change.  If we get caught in this window
  130.    * then we will fail to get the semaphore and the rc will indicate error.
  131.    */
  132.   if (ulProcessCount == 0)
  133.     { /* First process */
  134.  
  135.       if (!(rc = DosCreateMutexSem(pszProcCntMutexName,
  136.                                    &hmtxProcCnt,
  137.                                    0L,
  138.                                    TRUE)))
  139.         {
  140.           ulProcessCount++;
  141.         }
  142.     } /* First process */
  143.   else
  144.     { /* not first process */
  145.       /* if a process exits and decrements ProcessCount before we get  */
  146.       /* the semaphore here, we will fail. */
  147.       if (!(rc = DosOpenMutexSem(pszProcCntMutexName,
  148.                                  &hmtxProcCnt)))
  149.         {
  150.           if (!(rc = DosRequestMutexSem(hmtxProcCnt,
  151.                                         SEM_INDEFINITE_WAIT)))
  152.             {
  153.               ulProcessCount++;
  154.             }
  155.           else
  156.             {
  157.               DosCloseMutexSem(hmtxProcCnt);
  158.             }
  159.         }
  160.     } /* not first process */
  161.  
  162.   if (!rc)
  163.   { /* Semaphore ok, In critical section */
  164.     /*
  165.      * If this is the first time this init routine is called then we are
  166.      * being brought in by the loader the first time, so we need to register
  167.      * with the SSM.
  168.      */
  169.     if (ulProcessCount == 1)
  170.       { /* First process */
  171.         smhRegParm.ulFunction = SMH_REGISTER;
  172.         smhRegParm.pszSHName = pszHandlerName;
  173.         smhRegParm.phidSrc = &SrcHandlerID;
  174.         smhRegParm.phidTgt = &TgtHandlerID;
  175.         smhRegParm.pshcfnEntry = ( PSHCFN ) ShcRouter;
  176.  
  177.         smhRegParm.ulFlags = 0L;
  178.         if (ulHandlerFlags & HANDLER_CAN_BE_SOURCE)
  179.           {
  180.             smhRegParm.ulFlags = REGISTER_SRC_HNDLR;
  181.           }
  182.         if (ulHandlerFlags & HANDLER_CAN_BE_TARGET)
  183.           {
  184.             smhRegParm.ulFlags |= REGISTER_TGT_HNDLR;
  185.           }
  186.         if (ulHandlerFlags & HANDLER_IS_NONSTREAMING)
  187.           {
  188.             smhRegParm.ulFlags |= REGISTER_NONSTREAMING;
  189.           }
  190.  
  191.         rc = SMHEntryPoint((PVOID)&smhRegParm);
  192.         /*
  193.          * If ok then allocate our memory pool (heap), since it is under
  194.          * semaphore control create and get the semaphore first.
  195.          */
  196.         if (!rc)
  197.           { /* Register ok */
  198.             Registered = TRUE;
  199.             hHeap = HhpCreateHeap(HEAPSIZE,
  200.                                   HH_SHARED);
  201.             if (hHeap)
  202.               { /* Heap Allocated */
  203.                 HeapAllocated_Attached = TRUE;
  204.                 if (!(rc = DosCreateMutexSem(NULL,
  205.                                              &hmtxGlobalData,
  206.                                              DC_SEM_SHARED,
  207.                                              FALSE)))
  208.                   {
  209.                     GlobDataMtxCreated = TRUE;
  210.                   }
  211.               } /* Heap Allocated */
  212.             else
  213.               { /* Heap not allocated */
  214.                 rc = ERROR_ALLOC_RESOURCES;
  215.               } /* Heap not allocated */
  216.           } /* Register ok */
  217.       } /* First Process */
  218.     else
  219.       { /* Not first process */
  220.         if (!(rc = DosOpenMutexSem(NULL,
  221.                                    &hmtxGlobalData)))
  222.           { /* Global data semaphore opened */
  223.  
  224.             GlobDataMtxCreated = TRUE;
  225.  
  226.             if (!ENTERCRIT(rc))
  227.               { /* Global Data Sem obtained */
  228.  
  229.                 if (HhpAccessHeap(hHeap, HhpGetPID()))
  230.                   { /* Error accessing heap */
  231.                     rc = ERROR_ALLOC_RESOURCES;
  232.                   } /* Error accessing heap */
  233.                 else
  234.                   { /* Heap attached */
  235.                     HeapAllocated_Attached = TRUE;
  236.                   } /* Heap attached */
  237.  
  238.                 EXITCRIT;
  239.  
  240.               } /* Global Data Sem obtained */
  241.           } /* Global data semaphore opened */
  242.       } /* Not first process */
  243.  
  244.     /*
  245.      * If things are ok, Register an exit list handler and if that works
  246.      * increment the process count.
  247.      */
  248.     if (!rc)
  249.       {
  250.         rc = DosExitList(EXTLSTADD_ORDER,
  251.                          (PFNEXITLIST)ShExitList);
  252.       }
  253.  
  254.     if (rc)
  255.       { /* Error occurred - Clean Up */
  256.         if (HeapAllocated_Attached)
  257.           {
  258.             HhpReleaseHeap(hHeap,
  259.                            HhpGetPID());
  260.           }
  261.         if (GlobDataMtxCreated)
  262.           {
  263.             DosCloseMutexSem(hmtxGlobalData);
  264.           }
  265.         if (Registered)
  266.           { /* Deregister */
  267.             PARM_DEREG smhDeregParm;
  268.  
  269.             smhDeregParm.ulFunction = SMH_DEREGISTER;
  270.             smhDeregParm.pszSHName = pszHandlerName;
  271.             SMHEntryPoint(&smhDeregParm);
  272.           } /* Deregister */
  273.         ulProcessCount--;
  274.         DosReleaseMutexSem(hmtxProcCnt);
  275.         DosCloseMutexSem(hmtxProcCnt);
  276.       } /* Error occurred - Clean Up */
  277.     else
  278.       {
  279. #ifdef MMRAS_PTRACE
  280.         InitPTrace()
  281. #endif
  282.         DosReleaseMutexSem(hmtxProcCnt);
  283.       }
  284.  
  285.   } /* Semaphore ok, In critical section */
  286.   /*
  287.    * The return codes expected are:
  288.    *  TRUE (any non-zero) - init routine worked
  289.    *  FALSE (zero)        - init routine failed
  290.    *
  291.    * So we have to reverse the local rc before we pass it back.
  292.    */
  293.   return(!rc);
  294.  
  295. } /* End of SHInit */
  296.  
  297. /************************** START OF SPECIFICATIONS *************************/
  298. /*                                                                          */
  299. /* SUBROUTINE NAME: ShExitList                                              */
  300. /*                                                                          */
  301. /* DESCRIPTIVE NAME: Stream Hanlder Exit List routine                       */
  302. /*                                                                          */
  303. /* FUNCTION: Clean up resources allocated for each process, and if this is  */
  304. /*           the last process, then deregister with the SSM.                */
  305. /*           In all cases we need to destroy all streams owned by this      */
  306. /*           process.                                                       */
  307. /*                                                                          */
  308. /* ENTRY POINT:                                                             */
  309. /*   LINKAGE:   CALL NEAR (0:32)                                            */
  310. /*                                                                          */
  311. /* INPUT:                                                                   */
  312. /*                                                                          */
  313. /* EXIT-NORMAL: NO_ERROR (0)                                                */
  314. /*                                                                          */
  315. /* EXIT-ERROR:                                                              */
  316. /*   None                                                                   */
  317. /*                                                                          */
  318. /* SIDE EFFECTS:                                                            */
  319. /*                                                                          */
  320. /* INTERNAL REFERENCES:                                                     */
  321. /*        ROUTINES: None                                                    */
  322. /*                                                                          */
  323. /* EXTERNAL REFERENCES:                                                     */
  324. /*   ROUTINES:                                                              */
  325. /*     HhpGetPID                                                            */
  326. /*     DosRequestMutexSem                                                   */
  327. /*     DosCloseMutexSem                                                     */
  328. /*     SMHEntryPoint                                                        */
  329. /*     HhpShcDestroy                                                        */
  330. /*     DosExitList                                                          */
  331. /*     HhpReleaseHeap                                                       */
  332. /*     DosReleaseMutexSem                                                   */
  333. /*                                                                          */
  334. /*   DATA STRUCTURES:                                                       */
  335. /*     hmtxGlobalData                                                       */
  336. /*     hHeap                                                                */
  337. /*                                                                          */
  338. /*************************** END OF SPECIFICATIONS **************************/
  339.  
  340. VOID APIENTRY ShExitList()
  341.  
  342. { /* Start of ShExitList */
  343.  
  344. PSIB psib;                              /* Stream instance block */
  345. PSIB psibToDestroy = NULL;              /* Stream instance block to destroy */
  346. PARM_DESTROY dyparm;                    /* parameter block to destroy routine */
  347. PID  pid;                               /* Process ID */
  348. RC   rc;                                /* Return code */
  349.  
  350.   /*
  351.    * There is nothing we can do if calls fail, so don't bother checking.
  352.    */
  353.  
  354.   DosRequestMutexSem(hmtxProcCnt, SEM_INDEFINITE_WAIT);
  355.  
  356.   /*
  357.    * If this is the last process we will be removed from memory, so
  358.    * call SSM to deregister.
  359.    */
  360.  
  361.   if (ulProcessCount == 1)
  362.     {
  363.       PARM_DEREG smhDeregParm;
  364.  
  365.       smhDeregParm.ulFunction = SMH_DEREGISTER;
  366.       smhDeregParm.pszSHName = pszHandlerName;
  367.       SMHEntryPoint(&smhDeregParm);
  368.     }
  369.  
  370.   /* We need to call destroy for each stream created by this process. */
  371.   /*   Get the PID, and the global data semaphore. */
  372.   /*   Search the SIB chain for this process's stream instances. */
  373.   /*   Call destroy to destroy the stream instances */
  374.   /*   Release the global data semaphore */
  375.  
  376.   pid = HhpGetPID();
  377.  
  378.   ENTERCRIT(rc);
  379.   psib = pSIB_list_head;
  380.   while (psib)
  381.     {
  382.       if (psib->ProcessID == pid)
  383.         {
  384.           psibToDestroy = psib;
  385.           psib = psib->pnxtSIB;
  386.           if (psibToDestroy->ThreadID)
  387.             {
  388.               psibToDestroy->ulActionFlags |= SIBACTFLG_THREAD_DEAD;
  389.             }
  390.           dyparm.hstream = psibToDestroy->hStream;
  391.           dyparm.hid = psibToDestroy->HandlerID;
  392.           ShcDestroy(&dyparm);
  393.         }
  394.       else
  395.         {
  396.           psib = psib->pnxtSIB;
  397.         }
  398.     }
  399.  
  400.   /*
  401.    * Unattach from the memory pool, and from the Global data semaphore
  402.    */
  403.   HhpReleaseHeap(hHeap, pid);
  404.   EXITCRIT;
  405.   DosCloseMutexSem(hmtxGlobalData);
  406.  
  407.   /* Clean up the process count variable and it's semaphore. */
  408.  
  409.   ulProcessCount--;
  410.   DosReleaseMutexSem(hmtxProcCnt);
  411.   DosCloseMutexSem(hmtxProcCnt);
  412.  
  413.   DosExitList(EXLST_EXIT, (PFNEXITLIST)ShExitList);
  414.  
  415. } /* End of ShExitList */
  416.