static void _log_write_in_level(t_log* logger, t_log_level level, const char* message_template, va_list list_arguments) { if (_isEnableLevelInLogger(logger, level)) { char *message, *time, *buffer; unsigned int thread_id; message = string_from_vformat(message_template, list_arguments); time = temporal_get_string_time(); thread_id = process_get_thread_id(); buffer = string_from_format("[%s] %s %s/(%d:%d): %s\n", log_level_as_string(level), time, logger->program_name, logger->pid, thread_id, message); if (logger->file != NULL) { txt_write_in_file(logger->file, buffer); } if (logger->is_active_console) { txt_write_in_stdout(buffer); } free(time); free(message); free(buffer); } }
int escuchar(int puertoEscucha, int socketServer, int (*funcionParaProcesarMensaje)(int, header_t*, void*, t_log*), void* extra, t_log* logger) { int miPID = process_get_thread_id(); log_info(logger, "************** Comenzamos el proceso de escucha (PID: %d) ***************", miPID); //Logica principal para administrar conexiones fd_set masterFDList; //file descriptor list fd_set readFDList; //file descriptor list temporal para el select() int maxFDNumber; //maximo numero de file descriptor para hacer las busquedas en comunicaciones int socketEscucha;//socket escucha int nuevoFD;//file descriptor del cliente aceptado struct sockaddr_storage remoteaddr; //dirección del cliente socklen_t addrlen; char remoteIP[INET6_ADDRSTRLEN]; int socketActual; struct addrinfo hints; FD_ZERO(&masterFDList); //limpiamos la lista principal FD_ZERO(&readFDList); //limpiamos la lista de lectura //Lleno la estructura de tipo addrinfo memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; t_socket_info socketInfo; socketInfo.sin_addr.s_addr = INADDR_ANY; socketInfo.sin_family = AF_INET; socketInfo.sin_port = htons(puertoEscucha); memset(&(socketInfo.sin_zero), '\0', 8); socketEscucha = crearSocket(); bindearSocketYLoguear(socketEscucha, socketInfo, logger); // el socket se pone en modo server if (listen(socketEscucha, 10) == -1) { log_info(logger, "listen: %s", strerror(errno)); exit(3); } // agregamos el socket a la lista principal FD_SET(socketEscucha, &masterFDList); // guardamos el maximo numero de descriptor maxFDNumber = socketEscucha; if (socketServer > -1) { FD_SET(socketServer, &masterFDList); if (socketServer > maxFDNumber) { // grabamos el mayor FD maxFDNumber = socketServer; } } // log_info(logger, "socketEscucha %d", socketEscucha); // log_info(logger, "socketServer %d", socketServer); // log_info(logger, "maxFDNumber %d", maxFDNumber); for(;;){ readFDList = masterFDList; // copy it if (select(maxFDNumber+1, &readFDList, NULL, NULL, NULL) == -1) { log_info(logger, "select: %s", strerror(errno)); exit(4); } // recorremos las conexiones viendo si hay datos para leer for(socketActual = 0; socketActual <= maxFDNumber; socketActual++) { // log_debug(logger, "Reviso socket %d", socketActual); if (FD_ISSET(socketActual, &readFDList)) { // checkeamos si hay datos if (socketActual == socketEscucha) { // manejamos conexiones nuevas addrlen = sizeof remoteaddr; nuevoFD = accept(socketEscucha, (struct sockaddr *) &remoteaddr, &addrlen); if (nuevoFD == -1) { log_error(logger, string_from_format( "Hubo un error en el accept para el fd: %i", socketActual)); } else { FD_SET(nuevoFD, &masterFDList); // agregamos a la lista principal if (nuevoFD > maxFDNumber) { // grabamos el mayor FD maxFDNumber = nuevoFD; } void* inAddr = get_in_addr((struct sockaddr*) &remoteaddr); log_info(logger, string_from_format("Se recibe una nueva conexion desde %s en el socket %d\n", inet_ntop(remoteaddr.ss_family, inAddr, remoteIP, INET6_ADDRSTRLEN), nuevoFD)); } } else { header_t mensaje; int respRecibir = recibir_header_simple(socketActual, &mensaje); header_t* pMensaje = &mensaje; //if (pMensaje->tipo == ERR_CONEXION_CERRADA) { if (respRecibir == ERROR) { //Removes from master set and say good bye! :) close(socketActual); // bye! FD_CLR(socketActual, &masterFDList); // remove from master set log_info(logger, "El socket %d cerró la conexion.", socketActual); } else { log_debug(logger, "Recibi un header tipo: %d, tamanio: %d", pMensaje->tipo, pMensaje->largo_mensaje); FD_CLR(socketActual, &masterFDList); // remove from master set int result = funcionParaProcesarMensaje(socketActual, &mensaje, extra, logger); if(result == ERROR) { //Removes from master set and say good bye! :) close(socketActual); // bye! log_info(logger, "El socket %d cerró la conexion.", socketActual); } else { FD_SET(socketActual, &masterFDList); // agregamos a la lista principal } //FD_CLR(socketActual, &readFDList); //HACK faltaba limpiar, sino me traia los mensajes infinitamente } } //FD_CLR(socketActual, &readFDList); //HACK faltaba limpiar, sino me traia los mensajes infinitamente } } } return 0; }
void * procesarInstruccion() { t_log *logCpu; protocolo_planificador_cpu* datosParaProcesar = malloc(sizeof(protocolo_planificador_cpu)); protocolo_cpu_memoria* mensajeAMemoria = malloc( sizeof(protocolo_cpu_memoria)); protocolo_memoria_cpu* mensajeDeMemoria = malloc(sizeof(protocolo_memoria_cpu)); int tid = process_get_thread_id(); int socketPlanifAux; int maximoInstruccion = (int)(60.0f/config->retardo); t_list * listaTiempos = list_create(); // creacion de la instancia de log char* nombrelog = string_new(); string_append_with_format(&nombrelog,"../src/logCPU%d",tid); string_append(&nombrelog,".txt"); logCpu = log_create(nombrelog, "cpu.c", false, LOG_LEVEL_INFO); free(nombrelog); /*solo para que quede lindo cuando imprime*/ pthread_mutex_lock(&mutexConectarPlanificador); printf("Conectando CPU %d al Planificador (%s : %s)... ", tid, config->ipPlanificador,config->puertoPlanificador); client_init(&socketPlanifAux, config->ipPlanificador, config->puertoPlanificador); printf("OK\n"); pthread_mutex_unlock(&mutexConectarPlanificador); if (socketPlanifAux == -1) log_info(logCpu, "Fallo al conectar con Planificador"); else log_info(logCpu, "Conectado al Planificador"); if (socketMemoria == -1) log_info(logCpu, "CPU %d fallo al conectar con Memoria", tid); else log_info(logCpu, "CPU %d se conecto con Memoria", tid); int status; while (1) { status = deserializarPlanificador(datosParaProcesar, socketPlanifAux); if(status <= 0) pthread_exit(0); if(datosParaProcesar->tipoOperacion == 'u'){ /*tiempo actual*/ time_t tiempoActual = time(NULL); int i; int cantidadInstruccionesLeidas = 0; for(i = 0; i < list_size(listaTiempos); i++){ time_t * tiempoInstruccion = list_get(listaTiempos,i); if (tiempoActual - (*tiempoInstruccion) <= 60) cantidadInstruccionesLeidas++; } /*borro los tiempos de las isntrucciones que son anteriores al minuto*/ for(i = list_size(listaTiempos) - 1; i >= 0; i--){ time_t * tiempoInstruccion = list_get(listaTiempos,i); if (tiempoActual - (*tiempoInstruccion) > 60){ free(list_remove(listaTiempos,i)); } } datosParaProcesar->pid = tid; datosParaProcesar->counterProgram = ((int)(((float)cantidadInstruccionesLeidas/(float)maximoInstruccion) * 100.0f)); enviarAPlanificador(datosParaProcesar,socketPlanifAux); } else{ logueoRecepcionDePlanif(datosParaProcesar,tid,logCpu); FILE* archivo = fopen(datosParaProcesar->mensaje, "r+"); if (archivo == NULL){ printf("Error al abrir mCod: %s\n", datosParaProcesar->mensaje); break; } fseek(archivo, 0, SEEK_END); int tamanio = ftell(archivo); fseek(archivo, 0, SEEK_SET); char* lineaLeida = malloc(tamanio); int quantum = 0; while ((!feof(archivo) && (quantum < datosParaProcesar->quantum || datosParaProcesar->quantum == 0))) { //calcularTamanioDeLinea(archivo,&tamanio); char* instruccionLeida = leerInstruccion(&(datosParaProcesar->counterProgram), lineaLeida, archivo,tamanio); char** linea = string_split(instruccionLeida, ";"); printf("pid-> %d ejecutar %s\n", datosParaProcesar->pid, *linea); free(*linea); /*si no "entiende" la instruccion pasa a la siguiente*/ if (!interpretarInstruccion(instruccionLeida, datosParaProcesar, mensajeAMemoria, socketPlanifAux,logCpu)) continue; if (datosParaProcesar->tipoOperacion == 'e') break; /*asi la comunicacion con la memoria es atomica*/ pthread_mutex_lock(&mutex); enviarAMemoria(mensajeAMemoria); deserializarMemoria(mensajeDeMemoria, socketMemoria); pthread_mutex_unlock(&mutex); loguearEstadoMemoria(mensajeDeMemoria,instruccionLeida,logCpu); switch (mensajeDeMemoria->codOperacion){ case 'f': { actualizarOperacionPaquetePlanificador(datosParaProcesar, 'f'); enviarAPlanificador(datosParaProcesar,socketPlanifAux); /*me voy al eof para salir del while*/ while(getc(archivo) != EOF); continue; } break; case 'i':{ /*para saber desde el planifciador si el fallo es por inicializacion*/ datosParaProcesar->tipoProceso = 'i'; actualizarOperacionPaquetePlanificador(datosParaProcesar, mensajeDeMemoria->codAux); enviarAPlanificador(datosParaProcesar,socketPlanifAux); if (mensajeDeMemoria->codAux == 'a'){ /*me voy al eof para salir del while*/ while(getc(archivo) != EOF); continue; } } break; case 'l': case 'e':{ if (mensajeDeMemoria->codAux == 'a'){ /*para saber desde el planifciador si el fallo es por lectura o escritura*/ datosParaProcesar->tipoProceso = mensajeDeMemoria->codOperacion; actualizarOperacionPaquetePlanificador(datosParaProcesar, 'a'); enviarAPlanificador(datosParaProcesar,socketPlanifAux); datosParaProcesar->tipoOperacion = 'f'; /*me voy al eof para salir del while*/ while(getc(archivo) != EOF); continue; } } break; } sleep(config->retardo); /*guardo tiempo en el que se ejecuto la instruccion*/ time_t * tiempoInstruccion = malloc(sizeof(time_t)); *tiempoInstruccion = time(NULL); list_add(listaTiempos, tiempoInstruccion); /*incremento quatum solo para operaciones leer y escribir*/ if (mensajeDeMemoria->codOperacion != 'i' && mensajeDeMemoria->codOperacion != 'f') quantum++; } /*es rr y salio por quantum y no por io*/ if (datosParaProcesar->quantum != 0) { if (datosParaProcesar->quantum == quantum){ if (datosParaProcesar->tipoOperacion != 'e' && datosParaProcesar->tipoOperacion != 'f'){ actualizarOperacionPaquetePlanificador(datosParaProcesar, 'q'); enviarAPlanificador(datosParaProcesar, socketPlanifAux); printf("pid-> %d salio por quantum\n", datosParaProcesar->pid); } } } free(lineaLeida); fclose(archivo); } } free(mensajeAMemoria); free(mensajeDeMemoria); free(datosParaProcesar); close(socketPlanifAux); log_info(logCpu, "Cerrada conexion saliente"); log_destroy(logCpu); return 0; }
void escucha(int puerto) { int myPID = process_get_thread_id(); log_info(LOGGER, "************** Comienza a escuchar MaRTA a los Jobs (PID: %d) ***************",myPID); //Logica principal para administrar conexiones fd_set master; //file descriptor list fd_set read_fds; //file descriptor list temporal para el select() int fdmax; //maximo numero de file descriptor para hacer las busquedas en comunicaciones int listener;//socket escucha int newfd;//file descriptor del cliente aceptado struct sockaddr_storage remoteaddr; //dirección del cliente socklen_t addrlen; char remoteIP[INET6_ADDRSTRLEN]; int i; // socket entrante struct addrinfo hints; FD_ZERO(&master); //clear the master FD_ZERO(&read_fds); //clear the temp set //Lleno la estructura de tipo addrinfo memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; t_socket_info socketInfo; socketInfo.sin_addr.s_addr = INADDR_ANY; socketInfo.sin_family = AF_INET; socketInfo.sin_port = htons(puerto); memset(&(socketInfo.sin_zero), '\0', 8); listener = crearSocket(); bindearSocket(listener, socketInfo); // listen turns on server mode for a socket. if (listen(listener, 10) == -1) { perror("listen"); exit(3); } // add the listener to the master set FD_SET(listener, &master); // keep track of the biggest file descriptor fdmax = listener; // so far, it's this one for(;;){ read_fds = master; // copy it if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { perror("select"); exit(4); } // run through the existing connections looking for data to read for(i = 0; i <= fdmax; i++) { if (FD_ISSET(i, &read_fds)) { // we got one!! if (i == listener) { // handle new connections addrlen = sizeof remoteaddr; newfd = accept(listener, (struct sockaddr *) &remoteaddr, &addrlen); if (newfd == -1) { log_error(LOGGER, string_from_format( "Hubo un error en el accept para el fd: %i", i)); } else { FD_SET(newfd, &master); // add to master set if (newfd > fdmax) { // keep track of the max fdmax = newfd; } //Shows the new connection administrated log_info(LOGGER, string_from_format( "selectserver: new connection from %s on socket %d\n", inet_ntop(remoteaddr.ss_family, get_in_addr( (struct sockaddr*) &remoteaddr), remoteIP, INET6_ADDRSTRLEN), newfd)); } } else { header_t header; initHeader(&header); log_info(LOGGER, "Esperamos recibir mensajes de los Jobs"); if(recibir_header_simple(i, &header) != EXITO){ log_error(LOGGER, "Error al recibir header. Considero que viene de un cliente que se cayó"); header.tipo = ERR_CONEXION_CERRADA; } log_info(LOGGER, "Mensaje recibido! Header: %s", getDescription(header.tipo)); switch(header.tipo){ case ERR_CONEXION_CERRADA: close(i); FD_CLR(i, &master); job_eliminar(i, header); break; case JOB_TO_MARTA_FILES: // agrego el job a la lista sincronizada, gestiono las estructuras y blah job_agregar(i, header); // le pido al fs los bloques de los archivos del job y actualizo el job de la lista procesarArchivos(i, header); break; case JOB_TO_MARTA_MAP_OK: notificarMapOk(i, header); break; case JOB_TO_MARTA_MAP_ERROR: notificarMapError(i, header); break; case JOB_TO_MARTA_REDUCE_OK: notificarReduceOk(i, header); break; case JOB_TO_MARTA_REDUCE_ERROR: notificarReduceError(i, header); break; default: log_error(LOGGER, "ERROR mensaje NO RECONOCIDO (%d) !!\n", header); } } } } } }