Archived
3
0

ipc_application_select

This commit is contained in:
Philippe PITTOLI 2018-10-10 23:08:58 +02:00
parent ae7a6c404f
commit 6074fad02b
6 changed files with 205 additions and 3 deletions

View File

@ -105,3 +105,5 @@ void ipc_clients_free (struct ipc_clients *ap)
} }
ap->size = 0; ap->size = 0;
} }

View File

@ -1,5 +1,5 @@
#ifndef __IPC_PROCESS_H__ #ifndef __IPC_CLIENT_H__
#define __IPC_PROCESS_H__ #define __IPC_CLIENT_H__
struct ipc_client { struct ipc_client {
unsigned int version; unsigned int version;

View File

@ -210,3 +210,78 @@ int ipc_server_select (struct ipc_clients *clients, struct ipc_service *srv
return 0; return 0;
} }
/*calculer le max filedescriptor*/
static int getMaxFdServices(struct ipc_services *services)
{
int i;
int max = 0;
for (i = 0; i < services->size; i++ ) {
if (services->services[i]->service_fd > max) {
max = services->services[i]->service_fd;
}
}
return max;
}
/*
* ipc_application_select prend en parametre
* * un tableau de server qu'on écoute
* * le service qui attend de nouvelles connexions
* * un tableau de client qui souhaitent parler
*
* 0 = OK
* -1 = error
*/
int ipc_application_select (struct ipc_services *services, struct ipc_services *active_services)
{
assert (services != NULL);
assert (active_services != NULL);
// delete previous read active_services array
ipc_services_free (active_services);
int i, j;
/* master file descriptor list */
fd_set master;
fd_set readf;
/* maximum file descriptor number */
int fdmax;
/* clear the master and temp sets */
FD_ZERO(&master);
FD_ZERO(&readf);
for (i=0; i < services->size; i++) {
FD_SET(services->services[i]->service_fd, &master);
}
/* keep track of the biggest file descriptor */
fdmax = getMaxFdServices(services);
// printf ("loop ipc_server_select main_loop\n");
readf = master;
if(select(fdmax+1, &readf, NULL, NULL, NULL) == -1) {
perror("select");
return -1;
}
/*run through the existing connections looking for data to be read*/
for (i = 0; i <= fdmax; i++) {
// printf ("loop ipc_server_select inner loop\n");
if (FD_ISSET(i, &readf)) {
for(j = 0; j < services->size; j++) {
// printf ("loop ipc_server_select inner inner loop\n");
if(i == services->services[j]->service_fd ) {
ipc_service_add (active_services, services->services[j]);
}
}
}
}
return 0;
}

View File

@ -45,6 +45,6 @@ int ipc_application_close (struct ipc_service *);
int ipc_application_read (struct ipc_service *srv, struct ipc_message *m); int ipc_application_read (struct ipc_service *srv, struct ipc_message *m);
int ipc_application_write (struct ipc_service *, const struct ipc_message *m); int ipc_application_write (struct ipc_service *, const struct ipc_message *m);
int ipc_application_select (struct ipc_services *services, struct ipc_services *active_services);
#endif #endif

View File

@ -259,3 +259,107 @@ int usock_remove (const char *path)
{ {
return unlink (path); return unlink (path);
} }
// TODO: ipc_services functions
struct ipc_service * ipc_client_server_copy (const struct ipc_service *p)
{
if (p == NULL)
return NULL;
struct ipc_service * copy = malloc (sizeof(struct ipc_service));
memset (copy, 0, sizeof (struct ipc_service));
memcpy (copy, p, sizeof (struct ipc_service));
return copy;
}
int ipc_client_server_eq (const struct ipc_service *p1, const struct ipc_service *p2)
{
return (p1->version == p2->version && p1->index == p2->index
&& p1->service_fd == p2->service_fd && memcmp(p1->spath, p1->spath, PATH_MAX) == 0 );
}
void ipc_client_server_gen (struct ipc_service *p
, unsigned int index, unsigned int version)
{
p->version = version;
p->index = index;
}
int ipc_service_add (struct ipc_services *services, struct ipc_service *p)
{
assert(services != NULL);
assert(p != NULL);
services->size++;
services->services = realloc(services->services
, sizeof(struct ipc_service) * services->size);
if (services->services == NULL) {
return -1;
}
services->services[services->size - 1] = p;
return 0;
}
int ipc_service_del (struct ipc_services *services, struct ipc_service *p)
{
assert(services != NULL);
assert(p != NULL);
if (services->services == NULL) {
return -1;
}
int i;
for (i = 0; i < services->size; i++) {
if (services->services[i] == p) {
services->services[i] = services->services[services->size-1];
services->size--;
if (services->size == 0) {
ipc_services_free (services);
}
else {
services->services = realloc(services->services
, sizeof(struct ipc_service) * services->size);
if (services->services == NULL) {
return -2;
}
}
return 0;
}
}
return -3;
}
void service_print (struct ipc_service *p)
{
if (p != NULL)
printf ("client %d : index %d, version %d\n"
, p->service_fd, p->index, p->version);
}
void ipc_services_print (struct ipc_services *ap)
{
int i;
for (i = 0; i < ap->size; i++) {
printf("%d : ", i);
service_print(ap->services[i]);
}
}
void ipc_services_free (struct ipc_services *ap)
{
if (ap->services != NULL) {
free (ap->services);
ap->services = NULL;
}
ap->size = 0;
}

View File

@ -17,6 +17,11 @@ struct ipc_service {
int service_fd; int service_fd;
}; };
struct ipc_services {
struct ipc_service ** services;
int size;
};
/** /**
* for all functions: 0 ok, < 0 not ok * for all functions: 0 ok, < 0 not ok
*/ */
@ -50,4 +55,20 @@ int usock_remove (const char *path);
static inline int ipc_service_empty (struct ipc_service *srv) { srv = srv; return 0 ;}; static inline int ipc_service_empty (struct ipc_service *srv) { srv = srv; return 0 ;};
// store and remove only pointers on allocated structures
int ipc_service_add (struct ipc_services *, struct ipc_service *);
int ipc_service_del (struct ipc_services *, struct ipc_service *);
void ipc_services_print (struct ipc_services *);
void ipc_services_free (struct ipc_services *);
struct ipc_service * ipc_client_server_copy (const struct ipc_service *p);
int ipc_service_eq (const struct ipc_service *p1, const struct ipc_service *p2);
// create the client service structure
void ipc_client_server_gen (struct ipc_service *p
, unsigned int index, unsigned int version);
void service_print (struct ipc_service *);
#endif #endif