home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d105 / pere-et-fils.lha / Pere-et-Fils / pere.c < prev    next >
C/C++ Source or Header  |  1987-10-25  |  7KB  |  243 lines

  1. /**********************************************************************
  2.  *
  3.  *       fichier: pere.c    lanceur de process(s) et programme maitre
  4.  *
  5.  *       par Jean-Michel FORGEAS
  6.  *
  7.  *       creation: 09-Jun-87
  8.  *       revision: 18-Jun-87
  9.  *
  10.  **********************************************************************/
  11.  
  12.  
  13. /******* Included Files ***********************************************/
  14.  
  15. #include "proc.h"
  16.  
  17.  
  18. /******* Imported *****************************************************/
  19.  
  20. extern struct MsgPort *CreateProc();
  21. extern struct Pack    *GetMsg();
  22. extern int LoadSeg();
  23. extern int stdin;
  24.  
  25.  
  26. /******* Exported *****************************************************/
  27.  
  28. VOID main();
  29.  
  30.  
  31. /******* Program ******************************************************/
  32.  
  33. static VOID Manage();
  34. static VOID Quitte();
  35. static VOID DeleteUser();
  36. static struct Pack *CreatePack();
  37. static VOID DeletePack();
  38.  
  39. #define PRIORITY       0
  40. #define STACKSIZE   4000
  41.  
  42. struct MsgPort *InitPort, *MyPort=0;
  43. int    segment=0;
  44. int    ProcNum=0;
  45.  
  46.  
  47. /**********************************************************************
  48.  *
  49.  *      Point d'entree
  50.  *
  51.  **********************************************************************/
  52.  
  53.  
  54. /*-------------------------------------------------------------
  55.  *      chargement du code reentrant (pour cet exemple: fils.c)
  56.  */
  57.  
  58. VOID main(argc,argv)
  59. int  argc;
  60. char *argv[];      /* argv[1]=fichierdufils  argv[2]=nombredefilsalancer */
  61. {
  62.   int i=0, n=0;
  63.  
  64.     if (argc != 3) Quitte(1);
  65.     stcd_i( argv[2], &n );
  66.     if (n<=0) Quitte(0);
  67.                             /* premier port pour initialiser les fils */
  68.     if (!(InitPort = (struct MsgPort *) CreatePort( "Init", 0 ))) Quitte(5);
  69.                             /* second port pour causer avec les fils */
  70.     if (!(MyPort = (struct MsgPort *) CreatePort( "Pere", 0 ))) Quitte(5);
  71.  
  72.                             /* chargement du code qui supportera les fils */
  73.     if (!(segment = LoadSeg( argv[1] ))) Quitte(3);
  74.                             /* lancement de plusieurs process sur le code */
  75.     for (i=0; i<n; i++) if (CreateUser() != NO_ERROR) break;
  76.  
  77.     printf("--- %ld de partis sur %ls demandes\n",ProcNum,argv[2]);
  78.     if (ProcNum) Manage();
  79.               /* on quitte seulement si tous les fils sont termines */
  80.     Quitte(0);
  81. }
  82.  
  83.  
  84. /*------------------------------------------------------
  85.  *      usine a gaz de creation de process fils
  86.  */
  87.  
  88. static int CreateUser()
  89. {
  90.   struct MsgPort *FilsPort;
  91.   struct Pack *MyPack;
  92.   int i, rc;
  93.  
  94.     i = ProcNum+1;            /* nombre de fils + 1) */
  95.                               /* on alloue un message pour chaque fils */
  96.     if (!(MyPack = CreatePack( InitPort ))) return(NO_MEMORY);
  97.  
  98.     FilsPort = CreateProc( "fils", PRIORITY, segment, STACKSIZE );
  99.     if (!FilsPort)
  100.      {
  101.        printf("***Erreur CreateProc %ld: manque de memoire\n",i );
  102.        DeletePack( MyPack );
  103.        return( NO_MEMORY );
  104.      }
  105.                    /* on passe au fils son numero et son fichier a ouvrir */
  106.     MyPack->id   = i;
  107.     sprintf( MyPack->bufread, "CON:%ld/%ld/200/70/User %ld", 100+10*i, 50+9*i, i );
  108.  
  109.     PutMsg( FilsPort, MyPack );
  110.     WaitPort( InitPort );           /* le fils signale s'il est ok ou non */
  111.     MyPack = GetMsg( InitPort );
  112.     if ((rc = MyPack->result) != NO_ERROR)
  113.      {
  114.        printf("***Erreur fils %ld: %ld\n", i, rc );
  115.        DeletePack( MyPack );
  116.        return( rc );
  117.      }
  118.                                 /* on passe le fils sur l'autre port */
  119.     MyPack->msg.mn_ReplyPort = MyPort;
  120.                                 /* on lui demande de prompter et lire */
  121.     MyPack->cmd      = CMD_READ;
  122.     MyPack->lenread  = 256;
  123.     MyPack->bufwrite = "\n]";
  124.     MyPack->lenwrite = 2;
  125.                                 /* c'est parti: les caracteres lus seront */
  126.     PutMsg( MyPack->FilsPort, MyPack );  /* le fils a mis son port dans: */
  127.     ProcNum = i;                         /* MyPack->FilsPort... */
  128.     printf("fils numero %ld parti !\n", i);
  129.     return( NO_ERROR );
  130. }
  131.  
  132.  
  133. /*------------------------------------------------------
  134.  *      fume pas, bois pas, mais flingue
  135.  */
  136.  
  137. static VOID DeleteUser( pack )
  138. struct Pack *pack;
  139. {
  140.         /* l'utilisateur a passe par le fils une demande de "logoff" (fin) */
  141.     pack->cmd = CMD_STOP;          /* on arrete donc le fils */
  142.     PutMsg( pack->FilsPort, pack );
  143.                 /* le fils fait Forbid(), repond, puis se termine */
  144.     WaitPort( MyPort );
  145.     GetMsg( MyPort );     /* le fils est termine quand on prend le message */
  146.     DeletePack( pack );   /* effacement du message associe au fils */
  147.     ProcNum--;            /* nombre de fils actifs - 1 */
  148.     printf("un de moins, ");
  149.     if (ProcNum) printf("plus que %ld...\n",ProcNum);
  150.     else printf("c'etait le dernier !\n");
  151. }
  152.  
  153.  
  154. /*------------------------------------------------------
  155.  *      on attend une reponse d'un fils, et on renvoie
  156.  */
  157.  
  158. static VOID Manage()
  159. {
  160.  struct Pack *MyPack;
  161.  
  162.    while (TRUE)
  163.    {
  164.       WaitPort( MyPort );
  165.       MyPack = GetMsg( MyPort );
  166.  
  167.       if (MyPack->lenread==0)
  168.        {
  169.           MyPack->cmd = CMD_READ;
  170.        }
  171.       else
  172.        {
  173.           MyPack->bufread[ MyPack->lenread-1 ] = 0;
  174.           if (strcmp( MyPack->bufread, "logoff" ) == 0)
  175.            {
  176.               DeleteUser( MyPack );
  177.               if (!ProcNum) return;
  178.               continue;
  179.            }
  180.           else
  181.            {
  182.               MyPack->cmd      = CMD_READ;
  183.               MyPack->lenread  = 256;
  184.               MyPack->bufwrite = "d'accord mon pote\n]";
  185.               MyPack->lenwrite = 19;
  186.            }
  187.        }
  188.       PutMsg( MyPack->FilsPort, MyPack );
  189.    }
  190. }
  191.  
  192.  
  193. /*------------------------------------------------------
  194.  *      nettoyage et fin
  195.  */
  196.  
  197. static VOID Quitte(n)
  198. int n;
  199. {
  200.    switch (n)
  201.     {
  202.       case 0: printf("---Fin du père ok\n");         break;
  203.       case 1: printf("***Process fichier nbfils\n"); break;
  204.       case 2: printf("***Cannot Allocate memory\n"); break;
  205.       case 3: printf("***Cannot LoadSeg\n");         break;
  206.       case 4: printf("***Cannot CreateProc\n");      break;
  207.       case 5: printf("***Cannot CreatePort\n");      break;
  208.     }
  209.  
  210.    if (segment)  UnLoadSeg( segment );
  211.    if (MyPort)   DeletePort( MyPort );
  212.    if (InitPort) DeletePort( InitPort );
  213.  
  214.    exit(n);
  215. }
  216.  
  217.  
  218. /*-----------------------------------------------------
  219.  *      creation/effacement des structures de message
  220.  */
  221.  
  222. static struct Pack *CreatePack( ReplyPort )
  223. struct MsgPort  *ReplyPort;
  224. {
  225.  struct Pack *pack;
  226.  
  227.    pack = (struct Pack *) AllocMem( sizeof(struct Pack), MEMF_CLEAR | MEMF_PUBLIC );
  228.    if ( !pack) return ( (struct Pack *) 0);
  229.  
  230.    pack->msg.mn_Node.ln_Type = NT_MESSAGE;
  231.    pack->msg.mn_Length       = sizeof(struct Pack)-sizeof(struct Message);
  232.    pack->msg.mn_ReplyPort    = ReplyPort;
  233.  
  234.    return( pack );
  235. }
  236.  
  237. static VOID DeletePack( pack )
  238. struct Pack *pack;
  239. {
  240.    pack->msg.mn_Node.ln_Type = 0xFF;
  241.    FreeMem ( pack, sizeof(*pack) );
  242. }
  243.