Esta función crea un nuevo endpoint que sirve para poder emplear las funciones de enviar y recibir.
struct info_r
{
int id_cli; // valor del punto de acceso
};
struct info_w
{
int id_serv; // id del entidad de comunicaci\'on destino
int id_proc; // valor del punto de acceso de la aplicaci\'on
destino
};
typedef struct endpoint_info
{
char tipo; // 'r' o 'w'
union
{
struct info_r data_r;
struct info_w data_w;
} data;
} endpoint_info;
El endpoint puede ser para lectura o para escritura. Esto viene determinado por el contenido del campo tipo que será 'r' para lectura o 'w' para escritura. El resto del contenido de la estructura será de un tipo u otro según sea para especificar un punto de lectura o de escritura. En el caso de punto de escritura se indica la entidad de comunicación destino sobre la cual trabaja el servidor y el valor del punto de acceso del servidor. En el caso de lectura se indica el valor del punto de acceso que se desea emplear.
La aplicación que emplee este API no necesita conocer el contenido de la estructura endpoint dado que no la empleará directamente sino a través de funciones del API. Sin embargo esta es la estructura que se sugiere para el endpoint:
typedef struct endpoint
{
endpoint_info info; // El parametro de la funcion newendpoint()
int idnucleo; // ID de la entidad sobre la que trabaja
// Informacion para un endpoint de lectura
int idmem; // Identificador de la memoria compartida empleada
void *mem; // Puntero al comienzo de esa zona de memoria
int idsem1_paquetes,idsem2_huecos; // Identificadores de los
semaforos. 1=numero paquetes, 2=numero huecos
int paqleyendo; // Numero del siguiente paquete de la zona de
memoria (de 0 al numero maximo-1)
// Infomracion para un endpoint para escritura
int id_local; // Identificador de aplicacion origen a emplear
} endpoint;
En esta estructura la librería puede guardar toda la información necesaria para gestionar el endpoint. En el caso de un endpoint para escritura contiene la información necesaria del destino y del origen, donde como id_local se empleará en PID del proceso. En el caso de un endpoint para lectura contiene además los identificadores para emplear la memoria compartida y semáforos de comunicación entre el bloque
y la aplicación.
En el caso de la creación de un endpoint de escritura basta con almacenar en la nueva estructura la información necesaria. En el caso de uno de lectura además hay que reservar el valor de punto de acceso. Para ello la función newendpoint() envía un mensaje al bloque
indicando el valor que se desea emplear. El mensaje puede ser la estructura msg_ctrl_accept presentada a continuación:
typedef struct msg_ctrl_accept
{
int tipo; // Tipo de mensaje MSG_ACCEPT
int id_cli; // Valor de punto de acceso que se desea emplear
key_t clavecola; // clave de la cola de mensajes por la que se espera la confirmacion/rechazo
} msg_ctrl_accept;
El mensaje de respuesta que envía el bloque
como aceptación es:
typedef struct msg_ctrl_accept_ack
{
int tipo; // Tipo de mensaje MSG_ACCEPT_ACK
key_t clavemem; // clave de la zona de memoria compartida
key_t clavesem1; // clave del semaforo 1
key_t clavesem2; // clave del semaforo 2
} msg_ctrl_accept_ack;
O en caso de rechazo envía:
typedef struct msg_fin
{
int tipo; // Tipo de mensaje MSG_FIN
int id_cli; // El valor que no se ha podido reservar
} msg_fin;
Si no se ha podido reservar ese valor de punto de acceso la función newendpoint devuelve un indicador de error. Una vez tiene las claves de la memoria y los semáforos la librería puede acceder a ellos obtienendo los identificadores que guardará en la estructura endpoint.
Su valor de retorno es el nuevo endpoint o NULL en caso de error.