-
Notifications
You must be signed in to change notification settings - Fork 0
/
maestro_pizzero.c
92 lines (85 loc) · 4 KB
/
maestro_pizzero.c
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
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "lock_utils.h"
#include "debug_utils.h"
#include "panic_utils.h"
#include "random_utils.h"
#include "mensajes.h"
#include "resource_manager.h"
#include "constants.h"
#include "maestro_pizzero.h"
#define MALLOC_ERROR_EXIT_CODE -1
#define GETLINE_ERROR_EXIT_CODE -3
#define FREEING_RESOURCE_EXIT_CODE -4
#define LOCK_ERROR_EXIT_CODE -5
#define SPRINTF_ERROR_EXIT_CODE -30
int maestro_pizzero(FILE* pizzero_read_end, FILE* repartidor_write_end,
FILE* especialista_masas_read_end, FILE* pedidos_especialista_write_end,
FILE* pizzero_pipe_rd_lockfile, FILE* especialista_masa_rd_lockfile){
/*
Maestro pizzero:
El maestro pizzero recibe los pedidos del recepcionista y hornea las pizzas a medida el maestro de masa madre le provee la masa.
El tiempo de horneado es una variable aleatoria de distribucion uniforme, cuando termina entrega la pizza al repartidor
Devuelve 0 como exit code si fue exitoso, otro numero en caso contrario
*/
char* buffer = (char *)safe_malloc(DEFAULT_BUFFER_LEN * sizeof(char));
int por_entregar_ids[MAXIMO_SIMULTANEO_POR_COCINERO];
size_t por_entregar = 0;
size_t por_conseguir_masa_madre = 0;
size_t entregadas = 0;
if(!buffer) fatal_error_abort(FATAL_MALLOC, MALLOC_ERROR_EXIT_CODE);
memset(buffer, 0, DEFAULT_BUFFER_LEN);
info(INICIANDO_MAESTRO_PIZZERO);
int read_result = 0;
do {
if(por_entregar > 0){
if(sprintf(buffer, "%s%d", PIZZA_KEYWORD, por_entregar_ids[0]) < 0) fatal_error_abort(FATAL_SPRINTF, SPRINTF_ERROR_EXIT_CODE);
debug(ENTREGANDO_PIZZA, por_entregar_ids[0]);
if(write(fileno(repartidor_write_end), buffer, DEFAULT_BUFFER_LEN) > 0){
por_entregar--;
entregadas++;
for(size_t i=0; i<MAXIMO_SIMULTANEO_POR_COCINERO-1; i++) por_entregar_ids[i] = por_entregar_ids[i+1];
} else {
error(MAESTRO_PIZZERO_ERROR_AL_ENTREGAR, por_entregar_ids[0]);
}
} else if(por_conseguir_masa_madre > 0){
if(write(fileno(pedidos_especialista_write_end), MASA_KEYWORD, DEFAULT_BUFFER_LEN) > 0){
if(!acquire_exclusive_lock(fileno(especialista_masa_rd_lockfile))) fatal_error_abort(FATAL_ACQUIRE_LOCK, LOCK_ERROR_EXIT_CODE);
read_result = read(fileno(especialista_masas_read_end), buffer, DEFAULT_BUFFER_LEN);
release_locked_file(fileno(especialista_masa_rd_lockfile));
if(read_result < 0) fatal_error_abort(FATAL_LECTURA, GETLINE_ERROR_EXIT_CODE);
if(read_result > 0 && strncmp(buffer, MASA_KEYWORD, MASA_KEYWORD_LEN) == 0){
double tiempo_de_coccion = random_uniform(PIZZA_TIEMPO_LOWER_UNIFORM_VALUE, PIZZA_TIEMPO_UPPER_UNIFORM_VALUE);
debug(COCINANDO_PIZZA, por_entregar_ids[0], tiempo_de_coccion);
sleep(tiempo_de_coccion);
por_conseguir_masa_madre--;
por_entregar++;
} else if(read_result > 0){
error(ERROR_MENSAJE_NO_COMPRENDIDO, buffer);
}
} else {
error(MAESTRO_PIZZERO_PEDIDO_MASA_ERROR);
}
} else {
if(!acquire_exclusive_lock(fileno(pizzero_pipe_rd_lockfile))) fatal_error_abort(FATAL_ACQUIRE_LOCK, LOCK_ERROR_EXIT_CODE);
read_result = read(fileno(pizzero_read_end), buffer, DEFAULT_BUFFER_LEN);
release_locked_file(fileno(pizzero_pipe_rd_lockfile));
if(read_result < 0) fatal_error_abort(FATAL_LECTURA, GETLINE_ERROR_EXIT_CODE);
if(read_result > 0 && strncmp(buffer, PIZZA_KEYWORD, PIZZA_KEYWORD_LEN) == 0){
int id_actual = atoi(buffer+PIZZA_KEYWORD_LEN);
debug(PIDIENDO_MASA_MADRE_PIZZA, id_actual);
por_entregar_ids[por_entregar] = id_actual;
por_conseguir_masa_madre++;
} else if(read_result > 0){
error(ERROR_MENSAJE_NO_COMPRENDIDO, buffer);
}
}
} while(read_result || por_entregar);
info(MAESTRO_PIZZERO_STOP, entregadas);
free_all_resources();
return 0;
}