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