home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / VSCPPv8.zip / VACPP / IBMCPP / samples / COMPILER / SAMPLE05 / DLL / SAMPLE05.C next >
Text File  |  1995-03-22  |  12KB  |  307 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.             _rmem_init();
  96.             /* Create the shared mutex semaphore.                             */
  97.  
  98.             if ( ( rc = DosCreateMutexSem( SHARED_SEMAPHORE_NAME,
  99.                                            &hmtxSharedSem,
  100.                                            0,
  101.                                            FALSE ) ) != NO_ERROR )
  102.                {
  103.                printf( "DosCreateMutexSem rc = %lu\n", rc );
  104.                return 0;
  105.                }
  106.             }
  107.  
  108.          /* Register the current process.                                     */
  109.  
  110.          if ( DLLREGISTER( ) )
  111.             return 0;
  112.  
  113.          break;
  114.  
  115.       case 1:
  116.          /* De-register the current process.                                  */
  117.  
  118.          if ( DLLDEREGISTER( ) )
  119.             return 0;
  120.  
  121.          _rmem_term();
  122.  
  123.          break;
  124.  
  125.       default:
  126.          return 0;
  127.       }
  128.  
  129.    /* Indicate success.  Non-zero means success!!!                            */
  130.  
  131.    return 1;
  132.    }
  133.  
  134. /* DLLREGISTER - Registers the current process so that it can use this        */
  135. /*               subsystem.  Called by _DLL_InitTerm when the DLL is first    */
  136. /*               loaded for the current process.                              */
  137.  
  138. static unsigned long DLLREGISTER( void )
  139.    {
  140.    APIRET rc;
  141.    PTIB ptib;
  142.    PPIB ppib;
  143.  
  144.    /* Get the address of the process and thread information blocks.           */
  145.  
  146.    if ( ( rc = DosGetInfoBlocks( &ptib, &ppib ) ) != NO_ERROR )
  147.       {
  148.       printf( "DosGetInfoBlocks rc = %lu\n", rc );
  149.       return rc;
  150.       }
  151.  
  152.    /* Open the shared mutex semaphore for this process.                       */
  153.  
  154.    if ( ( rc = DosOpenMutexSem( SHARED_SEMAPHORE_NAME,
  155.                                 &hmtxSharedSem ) ) != NO_ERROR )
  156.       {
  157.       printf( "DosOpenMutexSem rc = %lu\n", rc );
  158.       return rc;
  159.       }
  160.  
  161.    /* Acquire the shared mutex semaphore.                                     */
  162.  
  163.    if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
  164.                                    SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
  165.       {
  166.       printf( "DosRequestMutexSem rc = %lu\n", rc );
  167.       DosCloseMutexSem( hmtxSharedSem );
  168.       return rc;
  169.       }
  170.  
  171.    /* Increment the count of processes registered.                            */
  172.  
  173.    ++ulProcessCount;
  174.  
  175.    /* Initialize the per-process data.                                        */
  176.  
  177.    ulProcessTotal = 0;
  178.    pidProcess = ppib->pib_ulpid;
  179.  
  180.    /* Tell the user that the current process has been registered.             */
  181.  
  182.    printf( "\nProcess %lu has been registered.\n\n", pidProcess );
  183.  
  184.    /* Release the shared mutex semaphore.                                     */
  185.  
  186.    if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
  187.       {
  188.       printf( "DosReleaseMutexSem rc = %lu\n", rc );
  189.       return rc;
  190.       }
  191.  
  192.    return 0;
  193.    }
  194.  
  195. /* DLLINCREMENT - Increments the process and global totals on behalf of the   */
  196. /*                calling program.                                            */
  197.  
  198. int DLLINCREMENT( int incount )
  199.    {
  200.    APIRET           rc;                     /* return code from DOS APIs      */
  201.  
  202.    /* Acquire the shared mutex semaphore.                                     */
  203.  
  204.    if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
  205.                                    SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
  206.       {
  207.       printf( "DosRequestMutexSem rc = %lu\n", rc );
  208.       return rc;
  209.       }
  210.  
  211.    /* Increment the counts the process and grand totals.                      */
  212.  
  213.    ulProcessTotal += incount;
  214.    ulGrandTotal += incount;
  215.  
  216.    /* Tell the user that the increment was successful.                        */
  217.  
  218.    printf( "\nThe increment for process %lu was successful.\n\n", pidProcess );
  219.  
  220.    /* Release the shared mutex semaphore.                                     */
  221.  
  222.    if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
  223.       {
  224.       printf( "DosReleaseMutexSem rc = %lu\n", rc );
  225.       return rc;
  226.       }
  227.  
  228.    return 0;
  229.    }
  230.  
  231. /* DLLSTATS  - Prints process and grand totals.                               */
  232.  
  233. int DLLSTATS( void )
  234.    {
  235.    APIRET          rc;
  236.  
  237.    /* Acquire the shared mutex semaphore.                                     */
  238.  
  239.    if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
  240.                                    SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
  241.       {
  242.       printf( "DosRequestMutexSem rc = %lu\n", rc );
  243.       return rc;
  244.       }
  245.  
  246.    /* Print out per-process and global information.                           */
  247.  
  248.    printf( "\nCurrent process identifier     = %lu\n", pidProcess );
  249.    printf( "Current process total          = %lu\n", ulProcessTotal );
  250.    printf( "Number of processes registered = %lu\n", ulProcessCount );
  251.    printf( "Grand Total                    = %lu\n\n", ulGrandTotal );
  252.  
  253.    /* Release the shared mutex semaphore.                                     */
  254.  
  255.    if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
  256.       {
  257.       printf( "DosReleaseMutexSem rc = %lu\n", rc );
  258.       return rc;
  259.       }
  260.  
  261.    return 0;
  262.    }
  263.  
  264. /* DLLDEREGISTER - Deregisters the current process from this subsystem.       */
  265. /*                 Called by _DLL_InitTerm when the DLL is freed for the      */
  266. /*                 last time by the current process.                          */
  267.  
  268. static unsigned long DLLDEREGISTER( void )
  269.    {
  270.    APIRET rc;
  271.  
  272.    /* Acquire the shared mutex semaphore.                                     */
  273.  
  274.    if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
  275.                                    SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
  276.       {
  277.       printf( "DosRequestMutexSem rc = %lu\n", rc );
  278.       return rc;
  279.       }
  280.  
  281.    /* Decrement the count of processes registered.                            */
  282.  
  283.    --ulProcessCount;
  284.  
  285.    /* Tell the user that the current process has been deregistered.           */
  286.  
  287.    printf( "\nProcess %lu has been deregistered.\n\n", pidProcess );
  288.  
  289.    /* Release the shared mutex semaphore.                                     */
  290.  
  291.    if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
  292.       {
  293.       printf( "DosReleaseMutexSem rc = %lu\n", rc );
  294.       return rc;
  295.       }
  296.  
  297.    /* Close the shared mutex semaphore for this process.                      */
  298.  
  299.    if ( ( rc = DosCloseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
  300.       {
  301.       printf( "DosCloseMutexSem rc = %lu\n", rc );
  302.       return rc;
  303.       }
  304.  
  305.    return 0;
  306.    }
  307.