next up previous
Next: int envia(endpoint* desc, const Up: Librería (práctica 4: 2 Previous: int putserverentry(int clave);

endpoint *newendpoint(endpoint_info *info);

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 $A$ 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 $A$ 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 $A$ 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.


next up previous
Next: int envia(endpoint* desc, const Up: Librería (práctica 4: 2 Previous: int putserverentry(int clave);
Daniel Morato 2000-11-06