home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / DBMIPC.ZIP / MASTER.C next >
Text File  |  1993-04-12  |  10KB  |  295 lines

  1. #define INCL_DOS
  2. #include <os2.h>
  3. #include <stdio.h>
  4. #include "master.h"               /* application defines */
  5.  
  6. main(argc, argv, envp)
  7.    int argc;
  8.    char *argv[];
  9.    char *envp[];
  10. {
  11.  int numdbs, i,j;
  12.  ULONG postct;                    /* used to hold reset count */
  13.  APIRET rc;                       /* return code from OS calls */
  14.  HEV master;                      /* My event semaphore handle*/
  15.  char execarg[60];                /* argument string for dosexecpgm */
  16.  char * imhere;                   /* work pointer */
  17.  char semname[100];               /* work are to hold semaphore name */
  18.  RESULTCODES result;              /* structure containing PID after dosexecpgm */
  19.  int Connectcount=0;              /* Number of databases connected when count
  20.                                      reaches zero this program will end */
  21.  
  22.  struct _commarea * SharedMem;    /* Pointer to memory shared with worker processes */
  23.  
  24. /*
  25.  *   If argument not passed in start default number of databases, otherwise
  26.  *   start the requested number (after validation of course)
  27.  *
  28. */
  29.  if (argc == 1)
  30.     numdbs=DBNAMECOUNT;
  31.  else
  32.  {
  33.     numdbs=atoi(argv[1]);
  34.     if (numdbs<1 || numdbs > DBNAMECOUNT)
  35.     {
  36.        printf("Maximum number of databases to be started is %ld you entered %ld\n",
  37.                 DBNAMECOUNT,numdbs);
  38.        DosExit(EXIT_PROCESS,8);
  39.     }
  40.  }
  41. /*    Allocate named shared memory object of size sufficient to hold
  42.  *    work areas for each of the databases to be started. Memory is
  43.  *    read/write and initially committed.
  44.  *
  45. */
  46.  rc=DosAllocSharedMem((void *)&SharedMem,SHARED_MEM_NAME,numdbs*sizeof(struct _commarea),
  47.                       PAG_COMMIT|PAG_READ|PAG_WRITE);
  48.  if (rc)
  49.  {
  50.     printf("DosAllocSharedMem failed rc= %ld\n",rc);
  51.     DosExit(EXIT_PROCESS,8);
  52.  
  53.  }
  54. /*
  55.  *    Create a named semaphore to be posted by workers when they
  56.  *    are finished their work. If work is to be done asynchronously
  57.  *    this code could be changed to handle multiple events and
  58.  *    periodically poll for completion or MUXWAIT.
  59.  *
  60. */
  61.  rc=DosCreateEventSem(MASTER_SEM_NAME,&master,0,0);
  62.  if (rc)
  63.  {
  64.     printf("DosCreateEventSem failed for Master Sem rc= %ld\n",rc);
  65.     DosExit(EXIT_PROCESS,8);
  66.  
  67.  }
  68. /*
  69.  *   Build the worker semaphore names.. each name will consist of
  70.  *   the required \SEM32\ followed by the database name. Each client
  71.  *   will open this semaphore and wait on it until there is work to do.
  72.  *
  73. */
  74.  memcpy(semname,"\\SEM32\\",7);
  75.  for (i=0;i<numdbs;i++)
  76.     {
  77.       strcpy(semname+7,dbNames[i]);
  78.       rc=DosCreateEventSem(semname,&dbSemaphores[i],0,0);
  79.       if (rc)
  80.       {
  81.          printf("DosCreateEventSem failed for %s rc= %ld\n",semname,rc);
  82.          DosExit(EXIT_PROCESS,8);
  83.  
  84.       }
  85. /*
  86.  *   Start the worker via DosExecPgm, passing an index into the
  87.  *   shared memory object where its control information will be.
  88.  *
  89. */
  90.  
  91.       strcpy(execarg,CLIENT_NAME);
  92.       j=strlen(execarg);
  93.       j++ ;
  94.       imhere=execarg+j;
  95.       sprintf(imhere,"%d",i);
  96.       imhere[strlen(imhere)+1]='\0';
  97.       rc=DosExecPgm(NULL,0L,EXEC_BACKGROUND,execarg,NULL,&result,CLIENT_NAME);
  98.       if (rc)
  99.       {
  100.          printf("DosExecProgram failed for %s rc= %ld\n",dbNames[i],rc);
  101.          DosExit(EXIT_PROCESS,8);
  102.  
  103.       }
  104. /*
  105.  *     Wait indefinitely for client to startup.. you might want to
  106.  *     change this code to wait with a timer and then check if the
  107.  *     PID is still valid, since it is possible for worker to die
  108.  *     because it can't open the semaphore or get memory or the like
  109.  *
  110. */
  111.       rc=DosWaitEventSem(master,SEM_INDEFINITE_WAIT);
  112.       if (rc)
  113.       {
  114.          printf("DosWaitEventSem failed for Master Sem rc= %ld\n",rc);
  115.          DosExit(EXIT_PROCESS,8);
  116.  
  117.       }
  118. /*
  119.  *  Reset the semaphore to clear the POST count so it can be waited on
  120.  *  again later
  121.  *
  122. */
  123.       rc=DosResetEventSem(master,&postct);
  124.       if (rc)
  125.       {
  126.          printf("DosResetEventSem failed for Master Sem rc= %ld\n",rc);
  127.          DosExit(EXIT_PROCESS,8);
  128.  
  129.       }
  130. /*
  131.  *     If its posted check the completion code from worker
  132.  *
  133. */
  134.       if (SharedMem[i].result == ITSOK)
  135.       {
  136.          printf("Process %ld started for database %s\n",
  137.                    result.codeTerminate,dbNames[i]);
  138.          Dbstate[i]=CONNECTED;
  139.          Connectcount++;
  140.       }
  141.       else
  142.          printf("Process %ld started for database %s .. but it had problems\n",
  143.                    result.codeTerminate,dbNames[i]);
  144.     }
  145.     /* begin servicing user requests */
  146.     while (Connectcount)
  147.     {
  148.        ULONG currentDb;
  149.        int action;
  150.        int value;
  151.        int newvalue;
  152.        int items;
  153.        struct _updatestuff  * stuff;
  154.        BOOL GoodRequest;
  155.        printf("\n__________________________________________________________\n");
  156.        printf("__________________________________________________________\n");
  157.        printf("enter request in the form of 'database number,Action,Value'\n");
  158.        printf("Where actions is 0 - terminate, 1 - update, 2 - insert, 3 -beep\n");
  159.        printf("Where database number is:\n");
  160.        for (i=0;i<numdbs;i++)
  161.        {
  162.           if (Dbstate[i]== CONNECTED)
  163.              printf("%ld for %s\n",i,dbNames[i]);
  164.        }
  165.        printf("__________________________________________________________\n");
  166.        printf("__________________________________________________________\n");
  167. /*
  168.  *    Not a very sophisticated user interface but it illustrates a point
  169.  *    get action, communicate information to the correct worker via
  170.  *    shared memory and semaphore, wait for completion and display results
  171.  *
  172. */
  173. /*
  174.  *
  175.  *
  176.  *
  177. */
  178.  
  179.        items = scanf("%lu,%ld,%ld",¤tDb,&action,&value);
  180.        if (items != EOF)
  181.        {
  182.           if (currentDb>numdbs || Dbstate[currentDb]== NOT_CONNECTED)
  183.           {
  184.              printf("The database number %ld is invalid or DB not connected\n",currentDb);
  185.           }
  186.           else
  187.           {
  188.             GoodRequest=TRUE;
  189. /*
  190.  *     REQTERM will tell worker to terminate
  191.  *     REQBEEP will tell worker to beep, different frequency for different dbs
  192.  *     REQUPDATE will take the value and use it as a key, and prompt for
  193.  *               a value to update.
  194.  *     REQINSERT will take the value and use it as a key, and prompt for
  195.  *               a additonal value to insert.
  196.  *
  197. */
  198.             switch (action) {
  199.             case REQTERM:
  200.                Dbstate[currentDb]= NOT_CONNECTED  ;
  201.                --Connectcount;
  202.                break;
  203.             case REQBEEP:
  204.                break;
  205.             case REQUPDATE:
  206.               printf("Enter the new value for key %ld\n",value);
  207.               items = scanf("%ld",&newvalue);
  208.               if (items == EOF)
  209.               {
  210.                printf("Ok update request cancelled\n");
  211.                GoodRequest=FALSE;
  212.               }
  213.               else
  214.               {
  215.                   stuff = (struct _updatestuff  *)SharedMem[currentDb].inarea;
  216.                   stuff->key=value;
  217.                   stuff->value=newvalue;
  218.               }
  219.                break;
  220.             case REQINSERT:
  221.               printf("Enter the new value for key %ld\n",value);
  222.               items = scanf("%ld",&newvalue);
  223.               if (items == EOF)
  224.               {
  225.                printf("Ok insert request cancelled\n");
  226.                GoodRequest=FALSE;
  227.               }
  228.               else
  229.               {
  230.                   stuff = (struct _updatestuff  *)SharedMem[currentDb].inarea;
  231.                   stuff->key=value;
  232.                   stuff->value=newvalue;
  233.               }
  234.                break;
  235.             default:
  236.                printf("unsupported action %ld\n",action);
  237.                GoodRequest=FALSE;
  238.                break;
  239.             } /* endswitch */
  240.             if (GoodRequest)
  241.             {
  242.                 SharedMem[currentDb].requestcode=action;
  243. /*
  244.  *   Tell the worker to look at his shared memory piece to find
  245.  *   his task.
  246.  *
  247. */
  248.                 rc=DosPostEventSem(dbSemaphores[currentDb]);
  249.                 if (rc)
  250.                 {
  251.                    printf("DosPostEventSem failed for worker Sem rc= %ld\n",rc);
  252.                    DosExit(EXIT_PROCESS,8);
  253.                 }
  254. /*
  255.  *         As I said earlier this could be made more sophisticated
  256.  *         to handle multiple requests asynchronously
  257.  *
  258. */
  259.                 rc=DosWaitEventSem(master,SEM_INDEFINITE_WAIT);
  260.                 if (rc)
  261.                 {
  262.                    printf("DosWaitEventSem failed for Master Sem rc= %ld\n",rc);
  263.                    DosExit(EXIT_PROCESS,8);
  264.  
  265.                 }
  266. /*
  267.  *          Reset the post count so that I can wait on it again
  268.  *
  269. */
  270.                 rc=DosResetEventSem(master,&postct);
  271.                 if (rc)
  272.                 {
  273.                    printf("DosResetEventSem failed for Master Sem rc= %ld\n",rc);
  274.                    DosExit(EXIT_PROCESS,8);
  275.                 }
  276.                 printf("return code and data from %s for action %ld is:\n",
  277.                             dbNames[currentDb],action);
  278.                 printf("result->%ld data->%s\n",
  279.                             SharedMem[currentDb].result,
  280.                             SharedMem[currentDb].outarea);
  281.             }
  282.           }
  283.        }
  284.     }
  285. /*
  286.  *       Clean up and go away
  287.  *
  288. */
  289.     printf("All connections gone I am going away\n");
  290.     DosCloseEventSem(master);
  291.     for (i=0;i<numdbs;i++)
  292.        DosCloseEventSem(dbSemaphores[i]);
  293.     DosFreeMem(SharedMem);
  294. }
  295.