void maitre(struct donneesPub *dp) { int i,n,a,bl; int clnt, reception; int r; char tmp[MAXLEN], *buf; struct flock request; struct s_test tLock; enum etat_t etat; char phraseTest[]="Ceci est une phrase test écrite par le maitre dans le fichier"; clnt=dp->nclnt; reception=dp->maitre[0]; etat=SELECT; /* On commence par le premier test */ n=0; printf("\n--------------------------------------\n"); while(1){ switch(etat){ case SELECT: /* Selection du test à effectuer*/ printf("\n"); E("Maitre: SELECT"); selectTest(n, &tLock); etat=tLock.type; bl=0; if(n<MAXTEST){ memset(tmp,0,MAXLEN); sprintf(tmp,"TEST : TRY TO %s:",LISTE_NOMS_TESTS[n]); write(0, tmp, strlen(tmp)); } else etat=FIN; P("etat=%d\n", etat); n+=1; continue; case RDONLY: /* Not reached */ case WRONLY: /* Not reached */ case READLOCK: P("Read lock :%d\n", etat); request.l_type=F_RDLCK; etat=LOCK; continue; case WRITELOCK: P("Write lock :%d\n", etat); request.l_type=F_WRLCK; etat=LOCK; continue; case LOCK: /* On applique le lock que l'on veut */ E("Maitre: LOCK"); write(dp->fd,phraseTest,strlen(phraseTest)); lockWholeFile(&request); if(fcntl(dp->fd, F_SETLK, &request)<0){ perror("Master: can't set lock\n"); perror("Echec\n"); exit(0); } sleep(1); E("Maitre"); etat=SYNC; continue; case BYTELOCK_READ: bl=1; request.l_type=F_RDLCK; etat=SYNC; continue; case BYTELOCK_WRITE: bl=1; request.l_type=F_WRLCK; etat=SYNC; continue; case BYTELOCK: /* L'idée est de faire locker l'ensemble du fichier octet par octet par un ensemble de sous processus * Il nous faut donc * -créer un fichier ayant autant d'octet que le nombre de processus passé en paramètres * -passer les sections à locker à chacun des esclaves * -vérifier que les locks sont bien appliqués * */ /* On crée une chaine de caractères à enregistrer dans le fichier qui contienne exactement un octet par * processus. */ P("Maitre: BYTELOCK: %d\n", etat); buf=(char *)malloc(clnt); memset(buf,'*', clnt); write(dp->fd, buf, clnt); request.l_whence=SEEK_SET; /* Chaque processus esclave reécrit son champs à locker. */ for(i=0;i<clnt;i++){ /* On renseigne la structure avec le lock qui va bien */ request.l_start=i; request.l_len=1; write(dp->lclnt[i][1], &request, sizeof(struct flock)); } etat=RESULTAT; continue; case SYNC: /* Synchronisation des processus esclaves. */ P("Maitre: SYNC %d\n", etat); /* On configure les esclaves pour le test */ for(i=0; i<clnt; i++) write(dp->lclnt[i][1], &(tLock.test), sizeof(int)); if(bl){ etat=BYTELOCK; continue; } if(n<MAXTEST+1) etat=RESULTAT; else etat=FIN; continue; case RESULTAT: /* On lit les résultats un par un */ E("Maitre: RESULTAT"); for(i=0; i<clnt; i++){ if((a=read(reception, &r,sizeof(int)))<0){ perror("Can't read master pipe"); exit(1); } compteur(r,n-1); } if(bl) validationResultats(n-1, dp); etat=CLEAN; continue; case CLEAN: a=CLEAN; for(i=0; i<clnt; i++) write(dp->lclnt[i][1], &a, sizeof(int)); /* Get CLEAN AcK from slaves */ for(i=0; i<clnt; i++){ if(read(reception, &a,sizeof(int))<0){ perror("Can't read master pipe"); exit(1); } } /* close and open file */ close(dp->fd); initTest(dp); etat=SELECT; continue; case FIN: a=FIN; for(i=0; i<clnt; i++) write(dp->lclnt[i][1], &a, sizeof(int)); break; printf("(end)\n"); exit(0); }/* switch */ break; }/* while */ rapport(clnt); }
void maitre() { int i, n, bl; int clnt; char tmp[MAXLEN], *buf; #ifdef DEBUG char dbg[16]; #endif struct flock request; struct s_test tLock; enum etat_t etat; int offset; /* A test sentence written in the file */ char phraseTest[] = "Ceci est une phrase test ecrite par le maitre dans le fichier"; bl = -1; clnt = dp.nclnt; maitreLecteur = dp.maitre[0]; etat = SELECT; /* On commence par le premier test. C'est original ;) */ /* Start with the first test ;) */ n = 0; printf("\n--------------------------------------\n"); while (1) { switch (etat) { case SELECT: /* Selection du test a effectuer */ /* Select the test to perform */ printf("\n"); E("Maitre: SELECT"); selectTest(n, &tLock); etat = tLock.type; bl = 0; if (n < MAXTEST) { memset(tmp, 0, MAXLEN); sprintf(tmp, "TEST : TRY TO %s:", LISTE_NOMS_TESTS[n]); write(0, tmp, strlen(tmp)); } else etat = FIN; P("etat=%d\n", etat); n += 1; continue; case RDONLY: case WRONLY: case READLOCK: P("Read lock :%d\n", etat); request.l_type = F_RDLCK; etat = LOCK; continue; case WRITELOCK: P("Write lock :%d\n", etat); request.l_type = F_WRLCK; etat = LOCK; continue; case LOCK: /* On applique le lock que l'on veut */ /* Apply the wanted lock */ E("Maitre: LOCK"); write(dp.fd, phraseTest, strlen(phraseTest)); lockWholeFile(&request); if (fcntl(dp.fd, F_SETLK, &request) < 0) { perror("Master: can't set lock\n"); perror("Echec\n"); exit(0); } E("Maitre"); etat = SYNC; continue; case BYTELOCK_READ: bl = 1; request.l_type = F_RDLCK; etat = SYNC; continue; case BYTELOCK_WRITE: bl = 1; request.l_type = F_WRLCK; etat = SYNC; continue; case BYTELOCK: /* * L'idee est de faire locker l'ensemble du fichier octet par octet par un ensemble de sous processus * Il nous faut donc * -creer un fichier ayant autant d'octet que le nombre de processus passe en parametres * -passer les sections a locker a chacun des esclaves * -verifier que les locks sont bien appliques * */ /* The main idea is to lock all the bytes in a file. Each slave process locks one byte. * * We need : * - To create a file of a length equal to the total number of slave processes * - send the exact section to lock to each slave * - ensure locks have been correctly set */ /* On cree une chaine de caracteres a enregistrer dans le fichier qui contienne exactement un octet par * processus. */ /* Create a string to record in the test file. Length is exactly the number of sub process */ P("Maitre: BYTELOCK: %d\n", etat); buf = malloc(clnt * (maxClients + 1)); memset(buf, '*', clnt); write(dp.fd, buf, clnt); free(buf); /* Chaque processus esclave reecrit son champs a locker. */ /* Each slave process re-writes its own field to lock */ request.l_whence = SEEK_SET; request.l_start = 0; request.l_len = 1; /* On commence par les envois reseau */ /* Start to send sections to lock to remote process (network clients) */ for (i = 0; i < maxClients; i++) { /* On renseigne la structure avec le lock qui va bien */ /* Set the correct byte to lock */ offset = (i + 1) * clnt; request.l_start = (off_t) offset; serverSendLockClient(&request, i); } /* Puis les envois locaux */ /* Now send sections to local processes */ for (i = 0; i < clnt; i++) { request.l_start = i; serverSendLockLocal(&request, i); } etat = RESULTAT; continue; case SYNC: sendLockTest(&tLock); if (bl) { etat = BYTELOCK; continue; } if (n < MAXTEST + 1) etat = RESULTAT; else etat = FIN; continue; case RESULTAT: /* On lit les resultats un par un */ /* Read results by one */ getResults(n - 1); if (bl) validationResultats(n - 1); etat = CLEAN; continue; case CLEAN: /* On demande aux clients d'arreter le test */ /* Ask the clients to stop testing ... */ tLock.test = CLEAN; serialiseTLock(&tLock); serverSend(); /* ... et on attend un accuse de reception avant de fermer */ /* ... and wait for an ack before closing */ serverReceive(); /* On ignore les resultats, ce n'est qu'un accuse de reception */ /* Ignore message content : that is only an ack */ /* close and open file */ close(dp.fd); initTest(dp); etat = SELECT; continue; case FIN: tLock.test = FIN; serialiseTLock(&tLock); serverSend(); sleep(2); break; printf("(end)\n"); exit(0); } /* switch */ break; } /* while */ rapport(clnt); }