From 6074fad02b52a96d388d85ae8c3573e2be7765ea Mon Sep 17 00:00:00 2001
From: Philippe PITTOLI
Date: Wed, 10 Oct 2018 23:08:58 +0200
Subject: [PATCH] ipc_application_select
---
core/client.c | 2 +
core/client.h | 4 +-
core/communication.c | 75 +++++++++++++++++++++++++++++++
core/communication.h | 2 +-
core/usocket.c | 104 +++++++++++++++++++++++++++++++++++++++++++
core/usocket.h | 21 +++++++++
6 files changed, 205 insertions(+), 3 deletions(-)
diff --git a/core/client.c b/core/client.c
index 8dcd542..1227cd6 100644
--- a/core/client.c
+++ b/core/client.c
@@ -105,3 +105,5 @@ void ipc_clients_free (struct ipc_clients *ap)
}
ap->size = 0;
}
+
+
diff --git a/core/client.h b/core/client.h
index 51cebf2..08d663c 100644
--- a/core/client.h
+++ b/core/client.h
@@ -1,5 +1,5 @@
-#ifndef __IPC_PROCESS_H__
-#define __IPC_PROCESS_H__
+#ifndef __IPC_CLIENT_H__
+#define __IPC_CLIENT_H__
struct ipc_client {
unsigned int version;
diff --git a/core/communication.c b/core/communication.c
index ed0cd01..02b158f 100644
--- a/core/communication.c
+++ b/core/communication.c
@@ -210,3 +210,78 @@ int ipc_server_select (struct ipc_clients *clients, struct ipc_service *srv
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;
+}
diff --git a/core/communication.h b/core/communication.h
index 7fdd90c..bc6e2a7 100644
--- a/core/communication.h
+++ b/core/communication.h
@@ -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_write (struct ipc_service *, const struct ipc_message *m);
-
+int ipc_application_select (struct ipc_services *services, struct ipc_services *active_services);
#endif
diff --git a/core/usocket.c b/core/usocket.c
index 794e194..2d61714 100644
--- a/core/usocket.c
+++ b/core/usocket.c
@@ -259,3 +259,107 @@ int usock_remove (const char *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;
+}
diff --git a/core/usocket.h b/core/usocket.h
index 75bf4ee..49fe891 100644
--- a/core/usocket.h
+++ b/core/usocket.h
@@ -17,6 +17,11 @@ struct ipc_service {
int service_fd;
};
+struct ipc_services {
+ struct ipc_service ** services;
+ int size;
+};
+
/**
* 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 ;};
+
+// 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