home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cset21v1.zip / IBMCPP / SAMPLES / COMPILER / SAMPLE05 / SAMPLE05.C < prev    next >
Text File  |  1993-03-15  |  12KB  |  304 lines

  1. #pragma strings( readonly )
  2. /******************************************************************************/
  3. /*                                                                            */
  4. /* SAMPLE05.C                                                                 */
  5. /*                                                                            */
  6. /* COPYRIGHT:                                                                 */
  7. /* ----------                                                                 */
  8. /* Copyright (C) International Business Machines Corp., 1991, 1993.           */
  9. /*                                                                            */
  10. /* DISCLAIMER OF WARRANTIES:                                                  */
  11. /* -------------------------                                                  */
  12. /* The following [enclosed] code is sample code created by IBM                */
  13. /* Corporation.  This sample code is not part of any standard IBM product     */
  14. /* and is provided to you solely for the purpose of assisting you in the      */
  15. /* development of your applications.  The code is provided "AS IS",           */
  16. /* without warranty of any kind.  IBM shall not be liable for any damages     */
  17. /* arising out of your use of the sample code, even if they have been         */
  18. /* advised of the possibility of such damages.                                */
  19. /*                                                                            */
  20. /* This example provides 5 external entrypoints of which 2 are exported for   */
  21. /* use by client processes.  The entrypoints are:                             */
  22. /*                                                                            */
  23. /* _DLL_InitTerm - Initialization/Termination function for the DLL that is    */
  24. /*                 invoked by the loader.  When the /Ge- compile option is    */
  25. /*                 used the linker is told that this is the function to       */
  26. /*                 execute when the DLL is first loaded and last freed for    */
  27. /*                 each process.                                              */
  28. /*                                                                            */
  29. /* DLLREGISTER  - Called by _DLL_InitTerm for each process that loads the     */
  30. /*                DLL.                                                        */
  31. /*                                                                            */
  32. /* DLLINCREMENT - Accepts a count from its client and adds this value to      */
  33. /*                the process and system totals.                              */
  34. /*                                                                            */
  35. /* DLLSTATS     - Dumps process and system totals on behalf of its client.    */
  36. /*                                                                            */
  37. /* DLLDEREGISTER- Called by _DLL_InitTerm for each process that frees the     */
  38. /*                DLL.                                                        */
  39. /*                                                                            */
  40. /******************************************************************************/
  41.  
  42. #define  INCL_DOS
  43. #define  INCL_DOSERRORS
  44. #define  INCL_NOPMAPI
  45. #include <os2.h>
  46. #include <stdio.h>
  47. #include "sample05.h"
  48.  
  49. unsigned long _System _DLL_InitTerm( unsigned long hModule, unsigned long ulFlag );
  50.  
  51. static unsigned long DLLREGISTER( void );
  52. static unsigned long DLLDEREGISTER( void );
  53.  
  54. #define SHARED_SEMAPHORE_NAME "\\SEM32\\SAMPLE05\\DLL.LCK"
  55.  
  56. /* The following data will be per-process data.  It will not be shared among  */
  57. /* different processes.                                                       */
  58.  
  59. static HMTX  hmtxSharedSem;    /* Shared semaphore                            */
  60. static ULONG ulProcessTotal;   /* Total of increments for a process           */
  61. static PID   pidProcess;       /* Process identifier                          */
  62.  
  63. /* This is the global data segment that is shared by every process.           */
  64.  
  65. #pragma data_seg( GLOBAL_SEG )
  66.  
  67. static ULONG ulProcessCount;                /* total number of processes      */
  68. static ULONG ulGrandTotal;                  /* Grand total of increments      */
  69.  
  70. /* _DLL_InitTerm() - called by the loader for DLL initialization/termination  */
  71. /* This function must return a non-zero value if successful and a zero value  */
  72. /* if unsuccessful.                                                           */
  73.  
  74. unsigned long _DLL_InitTerm( unsigned long hModule, unsigned long ulFlag )
  75.    {
  76.    APIRET rc;
  77.  
  78.    /* If ulFlag is zero then initialization is required:                      */
  79.    /*    If the shared memory pointer is NULL then the DLL is being loaded    */
  80.    /*    for the first time so acquire the named shared storage for the       */
  81.    /*    process control structures.  A linked list of process control        */
  82.    /*    structures will be maintained.  Each time a new process loads this   */
  83.    /*    DLL, a new process control structure is created and it is inserted   */
  84.    /*    at the end of the list by calling DLLREGISTER.                       */
  85.    /*                                                                         */
  86.    /* If ulFlag is 1 then termination is required:                            */
  87.    /*    Call DLLDEREGISTER which will remove the process control structure   */
  88.    /*    and free the shared memory block from its virtual address space.     */
  89.  
  90.    switch( ulFlag )
  91.       {
  92.       case 0:
  93.          if ( !ulProcessCount )
  94.             {
  95.             /* Create the shared mutex semaphore.                             */
  96.  
  97.             if ( ( rc = DosCreateMutexSem( SHARED_SEMAPHORE_NAME,
  98.                                            &hmtxSharedSem,
  99.                                            0,
  100.                                            FALSE ) ) != NO_ERROR )
  101.                {
  102.                printf( "DosCreateMutexSem rc = %lu\n", rc );
  103.                return 0;
  104.                }
  105.             }
  106.  
  107.          /* Register the current process.                                     */
  108.  
  109.          if ( DLLREGISTER( ) )
  110.             return 0;
  111.  
  112.          break;
  113.  
  114.       case 1:
  115.          /* De-register the current process.                                  */
  116.  
  117.          if ( DLLDEREGISTER( ) )
  118.             return 0;
  119.  
  120.          break;
  121.  
  122.       default:
  123.          return 0;
  124.       }
  125.  
  126.    /* Indicate success.  Non-zero means success!!!                            */
  127.  
  128.    return 1;
  129.    }
  130.  
  131. /* DLLREGISTER - Registers the current process so that it can use this        */
  132. /*               subsystem.  Called by _DLL_InitTerm when the DLL is first    */
  133. /*               loaded for the current process.                              */
  134.  
  135. static unsigned long DLLREGISTER( void )
  136.    {
  137.    APIRET rc;
  138.    PTIB ptib;
  139.    PPIB ppib;
  140.  
  141.    /* Get the address of the process and thread information blocks.           */
  142.  
  143.    if ( ( rc = DosGetInfoBlocks( &ptib, &ppib ) ) != NO_ERROR )
  144.       {
  145.       printf( "DosGetInfoBlocks rc = %lu\n", rc );
  146.       return rc;
  147.       }
  148.  
  149.    /* Open the shared mutex semaphore for this process.                       */
  150.  
  151.    if ( ( rc = DosOpenMutexSem( SHARED_SEMAPHORE_NAME,
  152.                                 &hmtxSharedSem ) ) != NO_ERROR )
  153.       {
  154.       printf( "DosOpenMutexSem rc = %lu\n", rc );
  155.       return rc;
  156.       }
  157.  
  158.    /* Acquire the shared mutex semaphore.                                     */
  159.  
  160.    if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
  161.                                    SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
  162.       {
  163.       printf( "DosRequestMutexSem rc = %lu\n", rc );
  164.       DosCloseMutexSem( hmtxSharedSem );
  165.       return rc;
  166.       }
  167.  
  168.    /* Increment the count of processes registered.                            */
  169.  
  170.    ++ulProcessCount;
  171.  
  172.    /* Initialize the per-process data.                                        */
  173.  
  174.    ulProcessTotal = 0;
  175.    pidProcess = ppib->pib_ulpid;
  176.  
  177.    /* Tell the user that the current process has been registered.             */
  178.  
  179.    printf( "\nProcess %lu has been registered.\n\n", pidProcess );
  180.  
  181.    /* Release the shared mutex semaphore.                                     */
  182.  
  183.    if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
  184.       {
  185.       printf( "DosReleaseMutexSem rc = %lu\n", rc );
  186.       return rc;
  187.       }
  188.  
  189.    return 0;
  190.    }
  191.  
  192. /* DLLINCREMENT - Increments the process and global totals on behalf of the   */
  193. /*                calling program.                                            */
  194.  
  195. int DLLINCREMENT( int incount )
  196.    {
  197.    APIRET           rc;                     /* return code from DOS APIs      */
  198.  
  199.    /* Acquire the shared mutex semaphore.                                     */
  200.  
  201.    if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
  202.                                    SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
  203.       {
  204.       printf( "DosRequestMutexSem rc = %lu\n", rc );
  205.       return rc;
  206.       }
  207.  
  208.    /* Increment the counts the process and grand totals.                      */
  209.  
  210.    ulProcessTotal += incount;
  211.    ulGrandTotal += incount;
  212.  
  213.    /* Tell the user that the increment was successful.                        */
  214.  
  215.    printf( "\nThe increment for process %lu was successful.\n\n", pidProcess );
  216.  
  217.    /* Release the shared mutex semaphore.                                     */
  218.  
  219.    if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
  220.       {
  221.       printf( "DosReleaseMutexSem rc = %lu\n", rc );
  222.       return rc;
  223.       }
  224.  
  225.    return 0;
  226.    }
  227.  
  228. /* DLLSTATS  - Prints process and grand totals.                               */
  229.  
  230. int DLLSTATS( void )
  231.    {
  232.    APIRET          rc;
  233.  
  234.    /* Acquire the shared mutex semaphore.                                     */
  235.  
  236.    if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
  237.                                    SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
  238.       {
  239.       printf( "DosRequestMutexSem rc = %lu\n", rc );
  240.       return rc;
  241.       }
  242.  
  243.    /* Print out per-process and global information.                           */
  244.  
  245.    printf( "\nCurrent process identifier     = %lu\n", pidProcess );
  246.    printf( "Current process total          = %lu\n", ulProcessTotal );
  247.    printf( "Number of processes registered = %lu\n", ulProcessCount );
  248.    printf( "Grand Total                    = %lu\n\n", ulGrandTotal );
  249.  
  250.    /* Release the shared mutex semaphore.                                     */
  251.  
  252.    if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
  253.       {
  254.       printf( "DosReleaseMutexSem rc = %lu\n", rc );
  255.       return rc;
  256.       }
  257.  
  258.    return 0;
  259.    }
  260.  
  261. /* DLLDEREGISTER - Deregisters the current process from this subsystem.       */
  262. /*                 Called by _DLL_InitTerm when the DLL is freed for the      */
  263. /*                 last time by the current process.                          */
  264.  
  265. static unsigned long DLLDEREGISTER( void )
  266.    {
  267.    APIRET rc;
  268.  
  269.    /* Acquire the shared mutex semaphore.                                     */
  270.  
  271.    if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
  272.                                    SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
  273.       {
  274.       printf( "DosRequestMutexSem rc = %lu\n", rc );
  275.       return rc;
  276.       }
  277.  
  278.    /* Decrement the count of processes registered.                            */
  279.  
  280.    --ulProcessCount;
  281.  
  282.    /* Tell the user that the current process has been deregistered.           */
  283.  
  284.    printf( "\nProcess %lu has been deregistered.\n\n", pidProcess );
  285.  
  286.    /* Release the shared mutex semaphore.                                     */
  287.  
  288.    if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
  289.       {
  290.       printf( "DosReleaseMutexSem rc = %lu\n", rc );
  291.       return rc;
  292.       }
  293.  
  294.    /* Close the shared mutex semaphore for this process.                      */
  295.  
  296.    if ( ( rc = DosCloseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
  297.       {
  298.       printf( "DosCloseMutexSem rc = %lu\n", rc );
  299.       return rc;
  300.       }
  301.  
  302.    return 0;
  303.    }
  304.