int deserializar_imprimir_valor(void * buffer) { int valor = 0; t_header * head = deserializar_header(buffer); valor = head->tamanio; free(head); return valor; }
void baja_de_personaje(char id_pj,t_nivel* nivel,ITEM_NIVEL** listaItems){ log_info(logger, "Ejecutando [baja_de_personaje]..."); t_list* recursos_a_orquestador = list_create(); log_info(logger, "[baja_de_personaje] Cargando recursos a orquestador..."); cargarRecursosAOrquestador(recursos_a_orquestador,id_pj,nivel->personajes_deadlock); //int* socket = socket_create_sin_puerto(); int* socket = socket_create(15000, logger); log_trace(logger, "Procesando [conectarse_a_orquestador]..."); if (socket_connect_with_retry(socket, nivel->ip, nivel->puerto, logger) < 0) { log_error(logger, "[baja_de_personaje] No pudo conectar"); exit(EXIT_FAILURE); } log_trace(logger, "Saliendo [baja_de_personaje]..."); int id_nivel = parsear_nivel(nivel->nombre); t_stream* stream=lista_liberados_serialize(recursos_a_orquestador,id_nivel); log_info(logger, "[baja_de_personaje] Sending bytes..."); sendBytes(socket,stream->data,stream->size, logger); log_info(logger, "[baja_de_personaje] Borrando item para id_pj=[%c]...", id_pj); BorrarItem(&nivel->lista_items,id_pj); liberarPersonaje(nivel->personajes_deadlock,id_pj); log_info(logger, "[baja_de_personaje] recibiendo del orquestador posibles personajes desbloqueados..."); char* data=receiveBytes(socket,sizeof(int)*2, logger); if(data!=NULL){ log_info(logger, "[baja_de_personaje] Deserializando data..."); t_header* header=(t_header*)deserializar_header(data); switch (header->tipo){ case NO_LIBERE: { log_info(logger, "[baja_de_personaje] Agregando a disponibles..."); agregarDisponibles(listaItems,recursos_a_orquestador); break; } case LIBERADOS: { log_info(logger, "[baja_de_personaje] Liberados -> Recibiendo del orquestador Personajes Desbloqueados..."); data = receiveBytes(socket,header->tamanio, logger); char* personajes = deserializar_liberados(data); actualizarPersonajesYActualizarDisponibles(personajes,nivel->personajes_deadlock,recursos_a_orquestador,listaItems); break; } } } log_info(logger, "[baja_de_personaje] cerrando socket=[%d]...", *socket); socket_close(socket, logger); log_info(logger, "Saliendo [baja_de_personaje]..."); }
int deserializar_cambio_proceso(void * buffer) { t_header * head = deserializar_header(buffer); if (head->identificador != (uint8_t) 18) { puts("Error en el header **cambio_proceso_activo**"); return -1; } int response = head->tamanio; free(head); return response; }
int deserializar_fin_prog(void * buffer) { t_header * head = deserializar_header(buffer); if (head->identificador != (uint8_t) 13) { puts("Error en el header **fin_programa**"); return -1; } int response = head->tamanio; free(head); return response; }
int deserializar_tamanio_pagina(void * buffer) { t_header * head = deserializar_header(buffer); if (head->identificador != (uint8_t) 19) { puts("Error en el header **tamaño_pagina**"); return -1; } int response = head->tamanio; free(head); return response; }
t_header * recibir_header(int socket) { void * buffer = malloc(5); int result = recv(socket, buffer, 5, 0); if (result <= 0) { //puts("Error en el recv del header"); return NULL; } t_header * header = deserializar_header(buffer); return header; }
int recibir_handshake(int socket) { void * buffer = malloc(5); int handshake_id = 0; int result = recv(socket, buffer, 5, 0); if (result == -1) { puts("Error en el recv del handshake"); return result; } if (result <= 0) return -1; t_header * header = deserializar_header(buffer); handshake_id = (int) header->identificador; free(header); return handshake_id; }
void recibir_mensaje(t_th_parametros_receive *parametros) { t_th_parametros_receive *parametros_receive = parametros; int bytes_recibidos_header; int bytes_recibidos_payload; char buffer_header[sizeof(t_header)]; int estoy_conectado = TRUE; while (estoy_conectado) { buffer_header[0] = '\0'; // Recibo header if ((bytes_recibidos_header = recv(parametros_receive->socket_cliente, buffer_header, sizeof(t_header), 0)) == -1) { estoy_conectado = FALSE; perror("recv header"); free(parametros); break; } // Verifico que el cliente no haya cerrado la conexion if (bytes_recibidos_header == 0) { perror("el socket cliente cerro la conexion\n"); estoy_conectado = FALSE; break; } else { t_paquete *paquete = malloc(sizeof(t_paquete)); paquete->header = malloc(sizeof(t_header)); deserializar_header(buffer_header, paquete->header); if (paquete->header->longitud_mensaje > 0) { paquete->payload = malloc(paquete->header->longitud_mensaje); // Recibo payload if ((bytes_recibidos_payload = recv( parametros_receive->socket_cliente, paquete->payload, paquete->header->longitud_mensaje, 0)) == -1) { estoy_conectado = FALSE; perror("recv payload"); break; } } else { //printf("\n payload vacio\n"); } void (*fn)() = parametros_receive->funcion; //ACA PREGUNTO SI LOS PARAMETROS SON NULL if (parametros_receive->parametros_funcion != NULL) { fn(paquete, parametros_receive->socket_cliente, parametros_receive->parametros_funcion); } else { fn(paquete, parametros_receive->socket_cliente); } if (paquete->header->longitud_mensaje > 0) { free(paquete->payload); } free(paquete->header); free(paquete); } } }
/* * La cola RR solo la agregamos por compatibilidad, * siempre va a ser un puntero a NULL. */ uint32_t atender_peticion_orquestador(uint32_t cliente, t_stream *pedido, t_queue_rr *cola_rr){ /*t_stream *pedido; recibir(cliente, (void*)&pedido); */ t_header header; deserializar_header(pedido, &header); int32_t pos_payload = sizeof(t_header); //char personajeElegido; switch (header.type){ case HANDSHAKE_NUEVO_NIVEL:{ uint32_t nro_nivel; uint32_t puerto; t_stream *payload = get_payload(pedido); memcpy(&nro_nivel,&payload[0],4); memcpy(&puerto,&payload[4],4); t_planificador *nodo_planificador; nodo_planificador = get_nodo_nivel(nro_nivel); //log_debug(logger_orq, "Hand_nuevo_nivel: dir nodo_planificador = %d", nodo_planificador); if(nodo_planificador == NULL){ nodo_planificador = malloc(sizeof(t_planificador)); nodo_planificador->tid=malloc(sizeof(pthread_t)); nodo_planificador->nivel.direccion = malloc(sizeof(struct sockaddr_in)); log_info(logger_orq, "Handshake_nuevo_nivel: Nueva conexión, nivel %d.", nro_nivel); completar_datos_nivel(nro_nivel, cliente, nodo_planificador); nodo_planificador->planificador.descriptor = 0; (nodo_planificador->nivel.direccion)->sin_port=htons(puerto); list_mutex_add(planificadores, (void*) nodo_planificador); sem_post(&semaforo_nodos_nuevos); free(pedido); return EXIT_SUCCESS; } log_info(logger_orq, "Se reconecta en nivel %d.", nro_nivel); completar_datos_nivel(nro_nivel, cliente, nodo_planificador); (nodo_planificador->nivel.direccion)->sin_port=htons(puerto); free(pedido); return EXIT_SUCCESS; } case HANDSHAKE_NUEVO_PJ:{ int8_t simbolo_pj; t_stream *payload =get_payload(pedido); simbolo_pj = (int8_t)payload[0]; log_info(logger_orq, "Handshake_nuevo_pj: Nueva conexión, pj %c", simbolo_pj); t_personaje_finalizado *pj; int pos_pj; pos_pj = get_pos_pj_finalizado(simbolo_pj); //Si todavía no está en la lista lo metemos. if(pos_pj == -1){ log_debug(logger_orq, "Handshake_nuevo_pj: El pj no existía así que lo guardo en listo personajes_finalizados."); pj = malloc(sizeof(t_personaje_finalizado)); pj->simbolo_pj = simbolo_pj; pj->termino_plan_de_niveles = false; log_debug(logger_orq, "Handshake_nuevo_pj: Guardo: Simbolo = %c bool_fin = %d", pj->simbolo_pj, pj->termino_plan_de_niveles); list_mutex_add(personajes_finalizados, (void*)pj); t_personaje_finalizado *test_pj = list_mutex_get(personajes_finalizados, 0); log_debug(logger_orq,"Handshake_nuevo_pj: Guardé simbolo = %c, bool_fin = %d ", test_pj->simbolo_pj, test_pj->termino_plan_de_niveles); } else{ pthread_mutex_lock(&personajes_finalizados->mutex); pj = list_get(personajes_finalizados->list, pos_pj); pj->termino_plan_de_niveles = false; pthread_mutex_unlock(&personajes_finalizados->mutex); } t_stream *stream_senial_ok; stream_senial_ok = serializar_senial(OK); log_debug(logger_orq, "Handshake_nuevo_pj: Envío OK al pj recién conectado"); enviar(cliente, stream_senial_ok); free(stream_senial_ok); free(pedido); return EXIT_SUCCESS; } case SOLICITUD_DATOS_NIVEL:{ t_stream *payload = get_payload(pedido); int8_t simbolo_pj = payload[0]; int8_t nro_nivel = payload[1]; t_datos_nivel datos_nivel; datos_nivel.direccion_nivel[0] = '\0'; datos_nivel.direccion_planificador[0]='\0'; int resultado = get_datos_nivel(nro_nivel, &datos_nivel); //Si el nivel no existe o si todavía no se lanzó su planificador asociado. if(resultado == EXIT_FAILURE){ char cadena_vacia = 'a'; t_stream *stream_nivel_no_existe = serializar_solicitud(NO_EXISTE_EL_NIVEL, sizeof(cadena_vacia), (t_stream*)&cadena_vacia); log_info(logger_orq, "Sol_datos_nivel: El pj %c solicitó los datos del nivel %d pero el nivel aún no fue cargado.", simbolo_pj, nro_nivel); enviar(cliente, (void*) stream_nivel_no_existe); free(pedido); free(stream_nivel_no_existe); return EXIT_SUCCESS; } t_stream *stream_datos_nivel; //En esta linea tira stream_datos_nivel = serializar_datos_nivel(&datos_nivel); log_debug(logger_orq,"Sol_datos_nivel: Datos del nivel solicitado: %s",datos_nivel.direccion_nivel); log_debug(logger_orq, "Sol_datos_nivel: Datos del planificador solicitado: %s",datos_nivel.direccion_planificador); log_info(logger_orq, "Sol_datos_nivel: El pj %c solicitó los datos del nivel %d. Se responde con los datos solicitados.", simbolo_pj, nro_nivel); enviar(cliente, stream_datos_nivel); free(stream_datos_nivel); free(pedido); return EXIT_SUCCESS; } case RECURSOS_LIBERADOS:{ //Los recursos vienen en un string con formato HHHHFFFFMMMM, char *recursos = (char*) &pedido[pos_payload]; uint32_t nro_nivel = get_nro_nivel(cliente); log_debug(logger_orq,"Recursos_liberados: Obteniendo socket_pair del planificador."); int32_t socket_pair_planificador = get_socket_pair_planificador(nro_nivel); log_debug(logger_orq,"Recursos_liberados: El socket pair es: %d", socket_pair_planificador); int32_t indice_recurso = 0; int8_t personaje_recurso[2]; int8_t personaje_nro_nivel[2]; log_info(logger_orq, "Recursos_liberados: El nivel %d liberó los recursos: %s ", nro_nivel, recursos); while(recursos[indice_recurso] != '\0'){ //La función pasa a un pj de bloqueados a personajes_listos. int8_t simbolo_pj_desbloqueado = desbloquear_personaje(recursos[indice_recurso], nro_nivel); if (simbolo_pj_desbloqueado>0) log_info(logger_orq,"Recursos_liberados: PJ elegido para desbloquear: %c, recurso: %c", simbolo_pj_desbloqueado, recursos[indice_recurso]); else log_info(logger_orq,"Recursos_liberados: Ningún pj esperaba el recurso %c", recursos[indice_recurso]); //Si no hay un pj que necesite ese recurso, en lugar del símbolo del pj envía -1. personaje_recurso[0] = simbolo_pj_desbloqueado; personaje_recurso[1] = recursos[indice_recurso]; t_stream *stream_pj_recurso = serializar_solicitud(DESBLOQUEAR_PERSONAJE, 2*sizeof(int8_t), (t_stream*) personaje_recurso); //Aviso al planificador para que lo saque de personajes_listo y lo ponga en cola_rr if(simbolo_pj_desbloqueado != -1){ personaje_nro_nivel[0] = simbolo_pj_desbloqueado; personaje_nro_nivel[1] = (int8_t) nro_nivel; log_debug(logger_orq,"Recursos_liberados: Envio al planificador pj: %c, nro_nivel: %d", personaje_nro_nivel[0], personaje_nro_nivel[1]); t_stream *stream_pj_nro_nivel = serializar_solicitud(DESBLOQUEAR_PERSONAJE, 2*sizeof(int8_t), (t_stream*) personaje_nro_nivel); int test_result_sock_pair = enviar(socket_pair_planificador, (void*) stream_pj_nro_nivel); if(test_result_sock_pair == EXIT_FAILURE) log_error(logger_orq,"Recursos_liberados: Error al enviar mensaje al socket_pair (nro %d)del planificador ", socket_pair_planificador); else log_debug(logger_orq,"Recursos_liberados: Se envió el msj al socket_pair nro %d", socket_pair_planificador); free(stream_pj_nro_nivel); } log_debug(logger_orq,"Recursos_liberados: Envio al nivel pj: %c, recurso: %c ", personaje_recurso[0], personaje_recurso[1]); enviar(cliente, (void*)stream_pj_recurso); free(stream_pj_recurso); //simbolo_pj_desbloqueado = desbloquear_personaje(recursos[indice_recurso], nro_nivel); indice_recurso++; } free(pedido); return EXIT_SUCCESS; } case FIN_PLAN_NIVELES:{ t_stream *payload = get_payload(pedido); int8_t simbolo_pj = payload[0]; log_info(logger_orq,"Fin_plan_niveles: El pj %c terminó su plan de niveles ", simbolo_pj); int pos_pj = get_pos_pj_finalizado(simbolo_pj); log_debug(logger_orq,"Fin_plan_niveles: Pos del pj finalizado = %d", pos_pj); t_personaje_finalizado *pj_finalizado = list_mutex_get(personajes_finalizados, pos_pj); pj_finalizado->termino_plan_de_niveles = true; if(todos_los_pj_terminaron()){ log_info(logger_orq,"Fin_plan_niveles: Todos los pj finalizaron su plan de niveles."); solicitar_fin_ejecucion_planificadores(); //Variable global que está en el while principal de todos los hilos. keep_running = false; estado_plataforma = false; sem_post(&semaforo_nodos_nuevos); } log_debug(logger_orq, "Fin_plan_niveles: FIN_PLAN_DE_NIVELES,case: retorno EXIT_SUCCESS;"); free(pedido); return EXIT_SUCCESS; } case RECOVERY:{ log_info(logger_orq, "Llegó pedido de recovery."); int8_t * personajesEnDeadlock = (int8_t*) &pedido[pos_payload]; printf("Llegó string: %s \n", personajesEnDeadlock); log_info(logger_orq, "Los PJs involucrados en el interbloqueo son %s", personajesEnDeadlock); t_personaje_listo *personajeElegido; int index_pj = 0; //Este while es solo por contención, se supone el pj[0] siempre va a estar bloqueado. while(personajesEnDeadlock[index_pj] != '\0'){ int8_t simbolo_pj = personajesEnDeadlock[index_pj]; personajeElegido= list_remove_personaje(personajes_bloqueados, simbolo_pj); if(personajeElegido != NULL){ log_info(logger_orq, "Recovery: Se da muerte al pj %c y se notifica al nivel.", personajeElegido->simbolo_pj); notificarPersonajeAsesinado(cliente, personajeElegido); if(index_pj != 0) log_info(logger_orq, "El pj asesinado estaba en la posición %d", index_pj); free(pedido); return EXIT_SUCCESS; } index_pj++; } log_error(logger_orq, "No se encontró ningún personaje para asesinar."); free(pedido); return EXIT_SUCCESS; } case HUBO_UNA_DESCONEXION:{ log_info(logger_orq, "Hubo una desconexión."); free(pedido); return EXIT_SUCCESS; } log_warning(logger_orq, "Hubo_desconexión: Recibo petición de tipo desconocida"); return EXIT_SUCCESS; } /* case RECOVERY:{//todo: agregar al serializador //todo: matar_personaje, func q devuelve el nombre de pj asesinado. //char *nombre_personaje = matar_personaje(); notificacion_pj_asesinado(cliente, nombre_personaje); free(nombre_personaje); free(pedido); //todo: poner free pedido fuera de atender_peticion()? return EXIT_SUCCESS; }*/ return EXIT_SUCCESS; }