2011-03-17 16:37:36 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
2011-03-19 12:29:52 +01:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/ipc.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <sys/sem.h>
|
2011-03-20 01:03:54 +01:00
|
|
|
#include <sys/shm.h>
|
2011-03-20 17:21:34 +01:00
|
|
|
|
2011-03-28 09:01:21 +02:00
|
|
|
#include <signal.h>
|
2011-03-20 17:21:34 +01:00
|
|
|
#include <curses.h>
|
|
|
|
#include <ctype.h>
|
2011-03-19 12:29:52 +01:00
|
|
|
#include "consommateur.h"
|
2011-03-17 16:57:53 +01:00
|
|
|
#include "types.h"
|
2011-03-19 12:29:52 +01:00
|
|
|
#include "sema.h"
|
|
|
|
#include "constantes.h"
|
2011-03-17 16:37:36 +01:00
|
|
|
|
2011-03-28 09:01:21 +02:00
|
|
|
void quitter(int signal);
|
2011-03-20 17:21:34 +01:00
|
|
|
WINDOW *creation_fenetre(int n,int d,char *t);
|
2011-03-24 00:56:31 +01:00
|
|
|
typedef struct prod_s
|
|
|
|
{
|
|
|
|
int idp;
|
|
|
|
WINDOW w;
|
|
|
|
} PROD;
|
2011-03-20 17:21:34 +01:00
|
|
|
|
2011-03-28 09:01:21 +02:00
|
|
|
int shmid, shm_key, i = 0;
|
|
|
|
int mutex_data, mutex_tpa;
|
|
|
|
key_t sem_key_data = MUTEX_DATA;
|
|
|
|
key_t sem_key_tpa = MUTEX_TPA;
|
|
|
|
|
2011-03-17 16:37:36 +01:00
|
|
|
int main( int argc, char **argv)
|
|
|
|
{
|
2011-03-28 12:17:38 +02:00
|
|
|
if(argc < 2)
|
|
|
|
{
|
|
|
|
printf("Usage : %s nSHM \n", argv[0]);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2011-03-19 12:29:52 +01:00
|
|
|
|
2011-03-20 17:21:34 +01:00
|
|
|
shm_key = (key_t) atoi(argv[1]);
|
2011-03-20 01:03:54 +01:00
|
|
|
MEMP * memoireP;
|
2011-03-24 00:56:31 +01:00
|
|
|
MEMP temp;
|
|
|
|
MSG msgtemp;
|
2011-03-28 00:14:37 +02:00
|
|
|
WINDOW *tWindow[MAX_PROD];
|
2011-03-17 17:31:26 +01:00
|
|
|
|
2011-03-20 23:27:26 +01:00
|
|
|
WINDOW *w ;
|
|
|
|
char c ;
|
|
|
|
|
2011-03-28 09:01:21 +02:00
|
|
|
signal(SIGHUP, quitter);
|
|
|
|
signal(SIGINT, quitter);
|
|
|
|
signal(SIGQUIT, quitter);
|
|
|
|
|
2011-03-20 01:03:54 +01:00
|
|
|
if((shmid = shmget(shm_key, sizeof(MEMP), IPC_CREAT|IPC_EXCL|0766)) == -1)
|
2011-03-28 09:55:25 +02:00
|
|
|
{
|
|
|
|
perror("shmget");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2011-03-20 01:03:54 +01:00
|
|
|
|
|
|
|
if((memoireP = (MEMP *) shmat(shmid, 0 , 0766)) == (void *) -1)
|
2011-03-28 09:55:25 +02:00
|
|
|
{
|
|
|
|
perror("shmat");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2011-03-20 01:03:54 +01:00
|
|
|
|
2011-03-20 01:21:44 +01:00
|
|
|
if((mutex_data = creat_sem( sem_key_data, 1)) == -1)
|
2011-03-28 09:55:25 +02:00
|
|
|
{
|
|
|
|
perror("creat_sem"); exit(EXIT_FAILURE);
|
|
|
|
}
|
2011-03-20 01:03:54 +01:00
|
|
|
|
2011-03-20 01:21:44 +01:00
|
|
|
if((mutex_tpa = creat_sem( sem_key_tpa, 1)) == -1)
|
2011-03-28 09:55:25 +02:00
|
|
|
{
|
|
|
|
perror("creat_sem");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2011-03-20 01:03:54 +01:00
|
|
|
|
2011-03-24 00:56:31 +01:00
|
|
|
temp.tete = 0;
|
|
|
|
temp.queue = 0;
|
2011-03-20 17:21:34 +01:00
|
|
|
|
2011-03-24 00:56:31 +01:00
|
|
|
for( i = 0; i < MAX_PROD ; i++)
|
|
|
|
temp.tpa[i] = -1;
|
|
|
|
|
|
|
|
P(mutex_data);
|
|
|
|
*memoireP = temp;
|
2011-03-20 01:03:54 +01:00
|
|
|
V(mutex_data);
|
|
|
|
|
2011-03-24 00:56:31 +01:00
|
|
|
// nbDeProd => est-ce qu'il y a des producteur (si 0 on quitte)
|
|
|
|
int nbDeProd;
|
2011-03-20 01:03:54 +01:00
|
|
|
|
2011-03-24 00:56:31 +01:00
|
|
|
// numTete est un entier qui détermine la "tête" courante. Si elle a changé, c'est qu'on a ajouté un caractère
|
|
|
|
int numTete = 0;
|
|
|
|
int vartemp;
|
2011-03-20 01:03:54 +01:00
|
|
|
|
2011-03-27 23:39:10 +02:00
|
|
|
// Variable temporaire qui indique le premier lancement du consommateur.c
|
|
|
|
// Si = 0 alors aucun producteur ne s'est connecté, on ne quitte pas le programme
|
|
|
|
// Si != 0 et si nbDeProd = 0 alors on quitte
|
|
|
|
int premier_lancement = 0;
|
|
|
|
|
2011-03-28 09:55:25 +02:00
|
|
|
initscr() ; /* initialisation (obligatoire) de curses */
|
|
|
|
noecho() ; /* suppression de l'echo des caracteres tapes*/
|
|
|
|
cbreak() ; /* lecture non bufferisee */
|
|
|
|
|
2011-03-28 00:14:37 +02:00
|
|
|
for( i = 0; i < MAX_PROD; i++)
|
|
|
|
{
|
|
|
|
tWindow[i] = creation_fenetre(LINES / MAX_PROD, i*(LINES/MAX_PROD), "En attente");
|
|
|
|
}
|
2011-03-20 17:21:34 +01:00
|
|
|
|
2011-03-20 23:27:26 +01:00
|
|
|
while (1)
|
2011-03-20 17:21:34 +01:00
|
|
|
{
|
2011-03-24 00:56:31 +01:00
|
|
|
// On (re)met nbDeProd à 0
|
|
|
|
nbDeProd = 0;
|
|
|
|
|
2011-03-27 23:39:10 +02:00
|
|
|
// On vérifie qu'il y ait toujours des producteurs
|
|
|
|
P(mutex_tpa);
|
2011-03-24 00:56:31 +01:00
|
|
|
for(i = 0 ; i < MAX_PROD && nbDeProd == 0 ; i++ )
|
2011-03-27 23:39:10 +02:00
|
|
|
{
|
2011-03-24 00:56:31 +01:00
|
|
|
if(memoireP->tpa[i] != -1)
|
2011-03-27 23:39:10 +02:00
|
|
|
{
|
2011-03-24 00:56:31 +01:00
|
|
|
nbDeProd++;
|
2011-03-27 23:39:10 +02:00
|
|
|
premier_lancement++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
V(mutex_tpa);
|
2011-03-24 00:56:31 +01:00
|
|
|
|
2011-03-20 23:27:26 +01:00
|
|
|
P(mutex_data);
|
2011-03-24 00:56:31 +01:00
|
|
|
vartemp = (int) memoireP->tete;
|
2011-03-28 10:06:04 +02:00
|
|
|
msgtemp = (MSG) memoireP->f[( vartemp -1 + MAX_BUF) % MAX_BUF ];
|
2011-03-24 00:56:31 +01:00
|
|
|
V(mutex_data);
|
|
|
|
|
|
|
|
if(numTete != vartemp)
|
2011-03-20 23:27:26 +01:00
|
|
|
{
|
2011-03-24 00:56:31 +01:00
|
|
|
numTete = vartemp;
|
|
|
|
c = msgtemp.c;
|
2011-03-28 00:14:37 +02:00
|
|
|
w = tWindow[msgtemp.idp];
|
2011-03-24 00:56:31 +01:00
|
|
|
|
2011-03-20 23:27:26 +01:00
|
|
|
waddch(w,c) ;
|
|
|
|
wrefresh(w) ;
|
|
|
|
}
|
2011-03-21 00:18:49 +01:00
|
|
|
|
2011-03-24 00:56:31 +01:00
|
|
|
P(mutex_data);
|
2011-03-28 10:06:04 +02:00
|
|
|
memoireP->queue = (memoireP->tete -1 + MAX_BUF) % MAX_BUF;
|
2011-03-24 00:56:31 +01:00
|
|
|
V(mutex_data);
|
2011-03-20 23:27:26 +01:00
|
|
|
|
|
|
|
// S'il n'y a plus de producteurs, on quitte
|
2011-03-27 23:39:10 +02:00
|
|
|
if(nbDeProd == 0 && premier_lancement != 0)
|
2011-03-20 23:27:26 +01:00
|
|
|
{
|
2011-03-28 09:28:14 +02:00
|
|
|
quitter(PLUSDEPROD);
|
2011-03-20 23:27:26 +01:00
|
|
|
}
|
2011-03-28 00:14:37 +02:00
|
|
|
// Ralentissement volontaire du programme
|
|
|
|
// Pour cause d'utilisation excessive de CPU
|
|
|
|
usleep(2);
|
2011-03-20 17:21:34 +01:00
|
|
|
}
|
2011-03-20 23:27:26 +01:00
|
|
|
exit(EXIT_FAILURE);
|
2011-03-17 16:37:36 +01:00
|
|
|
}
|
|
|
|
|
2011-03-20 17:21:34 +01:00
|
|
|
WINDOW *creation_fenetre(int n,int d,char *t)
|
|
|
|
{
|
|
|
|
WINDOW *cadre ; /* la fenetre pour le cadre */
|
|
|
|
WINDOW *w ; /* la fenetre de dialogue */
|
|
|
|
|
|
|
|
/* creation du cadre */
|
|
|
|
|
|
|
|
cadre= newwin(n,COLS,d,0) ;
|
|
|
|
box(cadre,0,0) ;
|
|
|
|
mvwprintw(cadre,0,COLS/2-strlen(t)/2,t) ;
|
|
|
|
wrefresh(cadre) ;
|
|
|
|
|
|
|
|
/* creation de la fenetre de dialogue */
|
|
|
|
|
|
|
|
w= newwin(n-2,COLS-2,d+1,1) ;
|
|
|
|
idlok(w,TRUE) ;
|
|
|
|
scrollok(w,TRUE) ; /* mise en place du defilement (scrolling) */
|
|
|
|
wclear(w) ;
|
|
|
|
wrefresh(w) ;
|
|
|
|
return w ;
|
|
|
|
}
|
2011-03-28 09:01:21 +02:00
|
|
|
|
|
|
|
void quitter(int signal)
|
|
|
|
{
|
|
|
|
if(shmctl(shmid, IPC_RMID, 0) < 0)
|
2011-03-28 10:06:04 +02:00
|
|
|
{
|
|
|
|
perror("shmctl");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2011-03-28 09:01:21 +02:00
|
|
|
|
2011-03-28 10:06:04 +02:00
|
|
|
if(mutex_data >= 0)
|
|
|
|
{
|
|
|
|
del_sem(sem_key_data);
|
|
|
|
}
|
|
|
|
if(mutex_tpa >= 0)
|
|
|
|
{
|
|
|
|
del_sem(sem_key_tpa);
|
|
|
|
}
|
2011-03-28 09:01:21 +02:00
|
|
|
|
|
|
|
endwin() ;
|
2011-03-28 09:28:14 +02:00
|
|
|
if(signal == PLUSDEPROD)
|
|
|
|
printf("Plus de producteurs.\n");
|
2011-03-28 09:01:21 +02:00
|
|
|
printf("FIN.\n");
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
}
|