/* Ficheros cabecera del sistema */ #include #include #include #include /* Ficheros cabecera de la aplicacion */ #include "tipo_shmem.h" #include "error_shmem.h" /* Constantes */ #define KEY_SEMAFORO #define KEY_SHMEM #define NUM_SEMAFOROS 1 #define NUM_OPERACIONES 1 #define SEMAFORO 0 #define DIM_MENSAJE 100 #define PERMISOS_IPC_SERV IPC_CREAT|0660 #define PERMISOS_IPC_CLIEN 0 #define VALOR_SEM 3 /* Operaciones de semaforos */ struct sembuf espero_servicio = {0, 0, 0}; /* Servidor */ struct sembuf pido_canal = {0, -2, 0}; /* Clientes */ struct sembuf pido_servicio = {0, -1, 0}; /* Clientes */ struct sembuf libero_canal = {0, 3, 0}; /* Servidor */ int semid, shmid ; char *buzon; /* Funcion de declaracion de uso de recursos IPC para el servidor */ int Pido_Recursos_Serv( void ) { int ret; /* Obtencion de mecanismos */ semid = semget( KEY_SEMAFORO, NUM_SEMAFOROS, PERMISOS_IPC_SERV ); if ( semid == -1 ) return( ERR_SEMGET ); shmid = shmget( KEY_SHMEM, DIM_MENSAJE, PERMISOS_IPC_SERV ); if ( shmid == -1 ) return( ERR_SHMGET ); /* Inicializacion de mecanismos */ if ( semctl( semid, SEMAFORO, SETVAL, VALOR_SEM ) == 1 ) return( ERR_SEMCTL); buzon = (char *)shmat( shmid, 0, 0 ); if ( buzon == (void *)-1 ) return( ERR_SHMAT ); return(NO_ERROR); } /* Funcion de declaracion de uso de recursos IPC para los clientes */ int Pido_Recursos_Clien( void ) { int ret; /* Obtencion de mecanismos */ semid = semget( KEY_SEMAFORO, NUM_SEMAFOROS, PERMISOS_IPC_CLIEN ); if ( semid == -1 ) return( ERR_SEMGET ); shmid = shmget( KEY_SHMEM, DIM_MENSAJE, PERMISOS_IPC_CLIEN ); if ( shmid == -1 ) return( ERR_SHMGET ); /* Inicializacion de mecanismos */ buzon = (char *)shmat( shmid, 0, 0 ); if ( buzon == (void *)-1 ) return( ERR_SHMAT ); return( NO_ERROR ); } /* Funcion invocada por el servidor para recibir peticiones de servicios */ int Espero_Peticion( mensaje buff ) { char *ret_char; /* Esperamos por solicitud de un servicio */ if ( semop( semid, &espero_servicio, NUM_OPERACIONES ) < 0 ) return( ERR_SEMOP ); /* Extraemos el contenido del mensaje */ ret_char = memcpy( buff, (const char *)buzon, DIM_MENSAJE ); return( NO_ERROR ); } /* Funcion invocada por los clientes para realizar una peticion */ int Solicito_Servicio( mensaje buff ) { char *ret_char; if ( semop( semid, &pido_canal, NUM_OPERACIONES ) < 0 ) { return( ERR_SEMOP ); } ret_char = memcpy( buzon, buff, DIM_MENSAJE ); if ( semop( semid, &pido_servicio , NUM_OPERACIONES ) < 0 ) { return( ERR_SEMOP ); } return( NO_ERROR ); } /* Funcion invocada por el servidor para permitir mas peticiones */ int Permito_Peticiones( void ) { int ret; if ( semop( semid, &libero_canal, NUM_OPERACIONES) < 0 ) { return( ERR_SEMOP ); } return( NO_ERROR ); } /* Funcion de liberacion de recursos ipc para clientes */ int Finaliza_Cliente( void ) { if ( shmdt( (void *)buzon ) < 0 ) return( ERR_SHMDT ); else return( NO_ERROR ); } /* Funcion de liberacion y borrado de recursos ipc para servidor */ int Finaliza_Servidor( void ) { if ( shmdt( (void *)buzon ) < 0 ) return( ERR_SHMDT ); if ( shmctl( shmid, IPC_RMID, (struct shmid_ds *)0 ) < 0 ) return( ERR_SHMCTL ); if ( semctl( semid, SEMAFORO, IPC_RMID, 0) < 0 ) return( ERR_SEMCTL ); return( NO_ERROR ); }