/* Fájlnév: term-fogy-takarito.c
   Az előadáson szereplő klasszikus termelő-fogyasztó problémára négy 
   fájlban adunk példát. 
   Elsőként kell futtatni az inicializáló programot, mely "elkészíti
   a raktárt": készít és inicializál szemaforkészletet a problémához.
   Ezután indíthatók tetszőleges sorrendben a termelők és a fogyasztók. 
   (A forrásprogramok a term-fogy-termelo.c és a term-fogy-fogyaszto.c).
   Célszerű ezeket a háttérben indítani és pid-jüket megjegyezni, ui. 
   SIGINT szignállal kell őket terminálni (a termelők és a fogyasztók 
   saját ütemükben végtelen ciklusban futnak). 
   Végül jelen kell futtatni, hogy a "takarítást" (szemafor megszüntetést) 
   elvégezzük. (E helyett persze az ipcrm paranccsal is "takaríthatunk"). 
   
   Elékezve az előadás példájára, három klasszikus (Dijkstra féle)
   szemafor kellene probléma kezeléséhez: egy mutex szemafor a ki-berakó 
   gép védelméhez, egy teli szemafor a raktár 
   telítettség kezelésére, és egy ures szemafor, a raktár üresség 
   kezeléshez. 
   Most mi a probléma megoldáshoz három elemi szemaforból álló készletet
   használuk, ahol a 0. indexű elemi szemafor lesz a mutex, az 1. indexű
   a teli, a 2. indexű az ures szemafor. 
   A szemafor megszüntetés előtt lekérdezzük az elemi szemafor értékeket
   a semctl( ) rendszerhívás GETALL parancsával. Figyeljék meg az 
   union semunion arg deklarációt!
   Készítette: dr. Vadász Dénes
   2006. február
  
*/
#include "mysem.h"

#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
	/* union semun a sys/sem.h-ban már definiált */
#else
	union semun {
		int    val;	      /* A GETVAL és SETVAL-hoz */
		struct semid_ds *buf; /* Az IPC_STAT és IPC_GET-hez */	
		ushort *array;	      /* A GETALL és SETALL-hoz */
	}
#endif
	
main() {
ushort 	  inittabla[3];		      /* A lekédezés eredményei ide. */
union semun arg; 		      /* A lekérdezés argumentuma */
int 	    id;			      /* A szemafor leírója */ 

/* Megnézzük, létezik-e már a szemafor. Ha igen, akkor lekérdezzük,
   majd megszüntetjük.
*/
	id = semget(TFKEY, 3, 0);
	if (id < 0) { /* Már nincs szemafor */
		perror(" Már nem létezik a szemafor. ");
		exit(-1);
	}

	/* Lekérdezzük az elemi szemafor értékeket. */
	arg.array = &inittabla[0]; /* A táblában a jönnek az értékek */
		
	if (semctl(id, 0, GETALL, arg) < 0) {
			perror(" Nem lehett lekérdezni. ");
			exit(-1);
	}
	/* Kiírjuk az értékeket. */
	printf("  A mutex: %d\n   A teli: %d\n Az ures: %d\n",
		arg.array[0], arg.array[1], arg.array[2]);
		
	/* Megszüntetjük a szemafort. */
	if (semctl(id, 0, IPC_RMID, 0) < 0) {
		perror(" Nem lehett törölni. ");
		exit(-1);
	}	
	/* Kész vagyunk */
	exit(0);
}
