-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMother.cpp
executable file
·215 lines (174 loc) · 5.52 KB
/
Mother.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/*************************************************************************
Mother - description
-------------------
date : Feb. 19 2014
copyright : (C) 2014 Yannick Marion & Gustave Monod
e-mail : [email protected]
*************************************************************************/
//---------- Realization of the <Mother> task (file Mother.cpp) ----------
///////////////////////////////////////////////////////////////// INCLUDE
//--------------------------------------------------------- System include
#include <cstdio> // for perror
#include <unistd.h> // for exit
#include <sys/wait.h> // for sigaction
#include <sys/ipc.h> // for all IPCS
#include <sys/shm.h> // for shmget
#include <sys/sem.h> // for semget
#include <sys/msg.h> // for msgget
//------------------------------------------------------- Personal include
#include "Heure.h"
#include "Outils.h"
#include "Information.h"
#include "Mother.h"
#include "Keyboard.h"
#include "EntranceDoor.h"
#include "ExitDoor.h"
///////////////////////////////////////////////////////////////// PRIVATE
//-------------------------------------------------------------- Constants
//------------------------------------------------------------------ Types
//------------------------------------------------------- Static variables
static int shmId;
static int shmMutexId;
static int mbCommandId;
static int waitSemSetId;
//------------------------------------------------------ Private functions
static void init ( );
// How to use:
static void destroy ( );
// How to use:
static void init ( )
// Algorithm:
// Initializes app, and creates the IPC objects used to communicate.
{
// First thing to do: Initialize app
InitialiserApplication( XTERM );
// Creating the shared memory
// (characteristics can be found in Information module)
shmId = shmget( ftok( PROGRAM_NAME, FTOK_CHAR ), SHM_SIZE,
IPC_CREAT | RIGHTS );
struct ParkingLot *shmParkingLot;
// Initialization of the shared memory
shmParkingLot = (struct ParkingLot *) shmat( shmId, NULL, 0 );
shmParkingLot->fullSpots = 0;
shmParkingLot->nextCarNo = 1;
for ( unsigned int i = 0; i < NB_BARRIERES_ENTREE; ++i )
{
( shmParkingLot->waitingCars[i] ).userType = AUCUN;
}
for ( unsigned int i = 0; i < NB_PLACES; ++i )
{
( shmParkingLot->parkedCars[i] ).userType = AUCUN;
}
// Initialization done, detaching memory
shmdt( shmParkingLot );
shmParkingLot = NULL;
// Creating the shared memory mutex
shmMutexId = semget( ftok( PROGRAM_NAME, FTOK_CHAR ), MUTEX_NB,
IPC_CREAT | RIGHTS );
// The shared memory is accessible, so the mutex is set to MUTEX_OK
semctl( shmMutexId, 0, SETVAL, MUTEX_OK );
// Creating the mailbox for the commands
mbCommandId = msgget( ftok( PROGRAM_NAME, FTOK_CHAR ),
IPC_CREAT | RIGHTS );
// Creating the semaphore set for the entrance doors to wait
waitSemSetId = semget( ftok( PROGRAM_NAME, FTOK_CHAR + 1 ),
NB_BARRIERES_ENTREE, IPC_CREAT | RIGHTS );
for ( unsigned int i = 0; i < NB_BARRIERES_ENTREE; ++i )
// For all semaphores in the set:
{
// By default, the entrance door should not let anyone in
semctl( waitSemSetId, i, SETVAL, MUTEX_KO );
}
}
static void destroy ( )
// Algorithm:
// Deletes the IPC objects used to communicate and destroys the app.
{
// Deletes all of the waiting semaphores
for ( unsigned int i = 0; i < NB_BARRIERES_ENTREE; ++i )
{
semctl( waitSemSetId, i, IPC_RMID, 0 );
}
// Deletes the command mailbox
msgctl( mbCommandId, IPC_RMID, 0 );
// Deletes the shared memory mutex
semctl( shmMutexId, 0, IPC_RMID, 0 );
// Deletes the shared memory
shmctl( shmId, 0, IPC_RMID );
// Terminates the app
TerminerApplication( );
_exit( EXIT_SUCCESS );
}
//static type name ( parameter list )
// How to use:
//
// Contract:
//
// Algorithm:
//
//{
//} //----- End of name
////////////////////////////////////////////////////////////////// PUBLIC
//------------------------------------------------------- Public functions
// type Name ( parameter list )
// Algorithm:
//
//{
//} //----- End of Name
int main ( )
{
init( );
// The pid of the multiple tasks
pid_t nbHour = ActiverHeure( );
pid_t nbExitDoor;
pid_t nbEntranceDoors[NB_BARRIERES_ENTREE];
pid_t nbKeyboard;
if ( 0 == ( nbExitDoor = fork( ) ) )
{
ExitDoor( );
perror( "Error while launching ExitDoor" );
_exit( EXIT_FAILURE );
}
else
{
for ( unsigned int i = 0; i < NB_BARRIERES_ENTREE; ++i )
{
nbEntranceDoors[i] = fork( );
if ( 0 == nbEntranceDoors[i] ) // Child process
{
// Giving the correct type of door as argument
EntranceDoor( ( TypeBarriere )( i + 1 ) );
perror( "Error while launching EntranceDoor" );
_exit( EXIT_FAILURE );
}
}
if ( 0 == ( nbKeyboard = fork( ) ) )
{
Keyboard( );
perror( "Error while launching Keyboard" );
_exit( EXIT_FAILURE );
}
else
{
// Waiting for end synchronization from Keyboard
waitpid( nbKeyboard, NULL, 0 );
// Killing the exit door
kill( nbExitDoor, SIGUSR2 );
waitpid( nbExitDoor, NULL, 0 );
// Killing the NB_BARRIERES_ENTREE entrance doors
for ( unsigned int i = 0; i < NB_BARRIERES_ENTREE; ++i )
{
kill( nbEntranceDoors[i], SIGUSR2 );
waitpid( nbEntranceDoors[i], NULL, 0 );
}
// Killing the Hour task
kill( nbHour, SIGUSR2 );
waitpid( nbHour, NULL, 0 );
// And finally, terminating the application
destroy( );
}
}
perror( "Error: bad exit at <Mother> task" );
_exit( EXIT_FAILURE );
}