home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / shmserve.zip / shmserve.c < prev    next >
C/C++ Source or Header  |  1998-12-04  |  8KB  |  285 lines

  1. /*  shmserve.c   v1.1
  2.  
  3.     This code sample illustrates the usage of suballocated shared memory
  4.     between two or more processes.
  5.  
  6.     shmserve.exe is the Server Process and should be running at all times.
  7.     shmclien.exe is the Client Process and can be run multiple times.
  8.  
  9.     A Named-Shared memory segment, called SHMSERVE.SHM is created by the
  10.     Server Process.  It is fairly small and includes various control
  11.     values found in SERVERCONTROLREC.  During startup, the Server Process
  12.     sub-allocates an initial pool of shared memory, and prepares it for
  13.     suballocation.  The address of this pool of memory is stored in the
  14.     (smaller) Named-Shared memory segment for rapid access by clients.
  15.  
  16.     When a Client Process is run, it attempts to read the Named-Shared
  17.     memory segment, whose presence signifies that a Server Process is
  18.     running.  The Client Process then tries to add some application
  19.     data (GLOM) to the pool of memory.
  20.  
  21.     Suballocated memory is more efficient in the use/reuse of memory,
  22.     than static blocks/pages of memory, especially with dynamic data
  23.     usage patterns.
  24.  
  25. */
  26.  
  27. /* (c) Copyright IBM Corp. 1998  All rights reserved.
  28.  
  29. This sample program is owned by International Business Machines
  30. Corporation or one of its subsidiaries ("IBM") and is copyrighted
  31. and licensed, not sold.
  32.  
  33. You may copy, modify, and distribute this sample program in any
  34. form without payment to IBM,  for any purpose including developing,
  35. using, marketing or distributing programs that include or are
  36. derivative works of the sample program.
  37.  
  38. The sample program is provided to you on an "AS IS" basis, without
  39. warranty of any kind.  IBM HEREBY  EXPRESSLY DISCLAIMS ALL
  40. WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED
  41. TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  42. PARTICULAR PURPOSE.
  43.  
  44. Some jurisdictions do not allow for the exclusion or limitation of
  45. implied warranties, so the above limitations or exclusions may not
  46. apply to you.  IBM shall not be liable for any damages you suffer
  47. as a result of using, modifying or distributing the sample program
  48. or its derivatives.
  49.  
  50. Each copy of any portion of this sample program or any derivative
  51. work,  must include a the above copyright notice and disclaimer of
  52. warranty.
  53. */
  54.  
  55. /************************************
  56.  * Define Constants
  57.  ************************************/
  58.  
  59. #define TRACE                      0
  60.  
  61. /************************************
  62.  * Include Files
  63.  ************************************/
  64.  
  65. #define INCL_DOSSEMAPHORES
  66. #define INCL_DOSMEMMGR
  67. #define INCL_DOS
  68. #define INCL_BASE
  69. #include <os2.h>
  70. #include <stdio.h>
  71. #include <stddef.h>
  72. #include <string.h>
  73. #include <stdlib.h>
  74.  
  75. #include <shmserve.h>
  76.  
  77.  
  78. /************************************
  79.  * Define Statics (data and private functions)
  80.  ************************************/
  81.  
  82. ULONG server_init      (SERVERCONTROLREC **pSrvCtlRec);
  83. ULONG server_term      (SERVERCONTROLREC **pSrvCtlRec);
  84.  
  85. /************************************
  86.  * Source Code Instructions
  87.  ************************************/
  88.  
  89. int main(argc, argv, envp)
  90.    int argc;
  91.    char *argv[];
  92.    char *envp[];
  93.   {
  94.     APIRET                rc        = NO_ERROR;   /* Return code */
  95.     CHAR                  tempch;
  96.     SERVERCONTROLREC     *pSrvCtlRec;
  97.  
  98.     printf("Shared-Memory Server\n");
  99.  
  100. #if TRACE > 0
  101.     printf("\nSetting up Shared Memory...\n");
  102. #endif
  103.  
  104.     rc = server_init(&pSrvCtlRec);
  105.     if (rc != 0)
  106.       {
  107.         return(1);
  108.       }
  109.  
  110.     printf("\nReady for Clients....(press any key to end Server)\n");
  111.  
  112.     tempch = getchar();
  113.  
  114.     rc = server_term(&pSrvCtlRec);
  115.  
  116.     return NO_ERROR;
  117.  
  118.  }
  119.  
  120. /* =====================================================================
  121.  *
  122.  * FUNCTION NAME:    server_init
  123.  *
  124.  * DESCRIPTIVE NAME: Initialize server internal memory
  125.  *
  126.  * DESCRIPTION:
  127.  *
  128.  * INPUT:
  129.  *
  130.  * OUTPUT:           Address to Server Control Record (Shared Memory)
  131.  *
  132.  * RETURN CODES:     OK - normal return
  133.  *
  134. ** ================================================================== */
  135. ULONG server_init      (SERVERCONTROLREC **pSrvCtlRec)
  136.   {
  137.     APIRET            ret;
  138.     PVOID             pSubBaseOffset;
  139.     SERVERCONTROLREC *SrvCtlRec;
  140.  
  141. #if TRACE > 0
  142.     printf("server_init starting\n");
  143. #endif
  144.  
  145.     // Get Shared Memory used for Server Control Record
  146.     ret = DosAllocSharedMem((PVOID *) pSrvCtlRec, SERVER_CONTROL_MEM_NAME,
  147.                             SCR_MEM_SIZE, PAG_WRITE | PAG_READ);
  148.     if (ret != 0)
  149.       {
  150. #if TRACE > 0
  151.         printf("DosAllocSharedMem ret= %d\n", ret);
  152. #endif
  153.         if (ret == ERROR_ALREADY_EXISTS)
  154.           {
  155.             printf("Another process is already running; probably a server\n");
  156.           }
  157.         return(ret);
  158.       }
  159.  
  160.     SrvCtlRec = *pSrvCtlRec;
  161.  
  162.     // Commit the 1st chunk to ensure that the Server Control Rec is
  163.     // always at the top of the allocated area.
  164.     ret = DosSetMem((PVOID) SrvCtlRec, SHMEMINIT,
  165.                     PAG_COMMIT | PAG_WRITE | PAG_READ );
  166.     if (ret != 0)
  167.       {
  168. #if TRACE > 0
  169.         printf("DosSetMem ret= %d\n", ret);
  170. #endif
  171.         DosFreeMem((PVOID) SrvCtlRec);
  172.         return(ret);
  173.       }
  174.  
  175.     // This is a pointer to the area that will be used as a Suballocation
  176.     // Pool for the Server Control Record.
  177.     pSubBaseOffset = (PVOID)(((PUCHAR) SrvCtlRec) + SHMEMINIT);
  178.  
  179.     // Initialize Heap area as uncommitted memory.
  180.     ret = DosSubSetMem(pSubBaseOffset, DOSSUB_INIT | DOSSUB_SPARSE_OBJ,
  181.                        INIT_SUBALLOC_MEM_SIZE);
  182.     if (ret != 0)
  183.       {
  184. #if TRACE > 0
  185.         printf("DosSubSetMem ret= %d\n", ret);
  186. #endif
  187.         DosFreeMem((PVOID) SrvCtlRec);
  188.         return(ret);
  189.       }
  190.  
  191.     SrvCtlRec->Server_Status = 2;      /* Don't want trx processed yet */
  192.     SrvCtlRec->SubAllocPool = pSubBaseOffset;
  193.     SrvCtlRec->SubAllocUsage = 0L;
  194.     SrvCtlRec->SubAllocAvail = INIT_SUBALLOC_MEM_SIZE;
  195.  
  196.     // Create the Semaphores used to access Service Control Record
  197.     ret = DosCreateMutexSem((PSZ)NULL, &(SrvCtlRec->SubAlloc_Lock),
  198.                             DC_SEM_SHARED, FALSE);
  199.     if (ret != 0)
  200.       {
  201.         printf("Unable to create SubAlloc_Lock semaphone %d\n", ret);
  202.         return(ret);
  203.       }
  204.  
  205.     // Create the Semaphores used to access Service Control Record
  206.     ret = DosCreateMutexSem((PSZ)NULL, &(SrvCtlRec->GLOM_List_Lock),
  207.                             DC_SEM_SHARED, FALSE);
  208.     if (ret != 0)
  209.       {
  210.         printf("Unable to create GLOM_List_Lock semaphone %d\n", ret);
  211.         return(ret);
  212.       }
  213.  
  214.     SrvCtlRec->Server_Status = 0;      /* running */
  215.  
  216. #if TRACE > 0
  217.     printf("server_init ending\n");
  218. #endif
  219.  
  220.     return(NO_ERROR);
  221.   }
  222.  
  223. /* =====================================================================
  224.  *
  225.  * FUNCTION NAME:    server_term
  226.  *
  227.  * DESCRIPTIVE NAME: Terminate server internal memory
  228.  *
  229.  * DESCRIPTION:      Free memory resources
  230.  *
  231.  * INPUT:
  232.  *
  233.  * OUTPUT:           Address to Server Control Record (Shared Memory)
  234.  *
  235.  * RETURN CODES:     OK - normal return
  236.  *
  237. ** ================================================================== */
  238. ULONG server_term      (SERVERCONTROLREC **pSrvCtlRec)
  239.   {
  240.     APIRET            ret;
  241.     PVOID             pSubBaseOffset;
  242.     SERVERCONTROLREC *SrvCtlRec;
  243.  
  244. #if TRACE > 0
  245.     printf("server_term starting\n");
  246. #endif
  247.  
  248.     SrvCtlRec = *pSrvCtlRec;
  249.  
  250.     // Close the Semaphores used to access Service Control Record
  251.     ret = DosCloseMutexSem(SrvCtlRec->SubAlloc_Lock);
  252.     SrvCtlRec->SubAlloc_Lock = 0L;
  253.  
  254.     // Close the Semaphores used to access Service Control Record
  255.     ret = DosCloseMutexSem(SrvCtlRec->GLOM_List_Lock);
  256.     SrvCtlRec->GLOM_List_Lock = 0L;
  257.  
  258.     SrvCtlRec->Server_Status = 2;      /* Don't want trx processed yet */
  259.  
  260.     ret = DosSubUnsetMem(SrvCtlRec->SubAllocPool);
  261.     if (ret != 0)
  262.       {
  263. #if TRACE > 0
  264.         printf("DosSubUnsetMem (Free) ret= %d\n", ret);
  265. #endif
  266.         return(1);
  267.       }
  268.  
  269.     ret = DosFreeMem((PVOID) SrvCtlRec);
  270.     if (ret != 0)
  271.       {
  272. #if TRACE > 0
  273.         printf("DosFreeMem  ret= %d\n", ret);
  274. #endif
  275.         return(1);
  276.       }
  277.  
  278.     *pSrvCtlRec = (PVOID) 0L;
  279.  
  280. #if TRACE > 0
  281.     printf("server_term ending\n");
  282. #endif
  283.  
  284.     return(NO_ERROR);
  285.   }