summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile2
-rw-r--r--src/ivy.c63
-rw-r--r--src/ivy.h16
-rw-r--r--src/version.h2
4 files changed, 76 insertions, 7 deletions
diff --git a/src/Makefile b/src/Makefile
index 4501aa6..98e1b8c 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -17,7 +17,7 @@
# change this in version.h too !!!!
MAJOR=3
-MINOR=13
+MINOR=14
PERHAPS64 := $(shell getconf LONG_BIT | perl -ne "print /64/ ? '64' : '';")
LIB = /lib$(PERHAPS64)
diff --git a/src/ivy.c b/src/ivy.c
index a87d24e..607c679 100644
--- a/src/ivy.c
+++ b/src/ivy.c
@@ -73,6 +73,8 @@ extern int WSAAPI inet_pton(int af, const char *src, void *dst);
* effectuée si on stringifie directement dans la macro GenerateIvyBus */
#define str(bus) #bus
#define GenerateIvyBus(domain,bus) str(domain)":"str(bus)
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
static const char* DefaultIvyBus = GenerateIvyBus(DEFAULT_DOMAIN,IVY_DEFAULT_BUS);
typedef enum {
@@ -122,6 +124,12 @@ struct _msg_snd_dict { /* requete de reception d'un client */
/* liste de clients, champ de la struct _msg_snd_dict qui est valeur du dictionnaire */
/* typedef IvyClientPtr */
+
+struct _ping_timestamp {
+ struct timeval ts;
+ int id;
+};
+
struct _clnt_lst_dict {
RWIvyClientPtr next;
Client client; /* la socket client */
@@ -135,9 +143,11 @@ struct _clnt_lst_dict {
#ifdef OPENMP
int endRegexpReceived;
#endif // OPENMP
- int readyToSend; /* comptage des endRegexps recu et emis */
- int ignore_subsequent_msg; /* pour ignore les messages venant
- d'une socket ferme, mais donc les donnees sont deja en buffer */
+ int readyToSend; /* comptage des endRegexps recu et emis */
+ int ignore_subsequent_msg; /* pour ignorer les messages venant
+ d'une socket ferme, mais donc les donnees sont deja en buffer */
+ struct _ping_timestamp ping_timestamp; /* on enregistre le timestamp du ping pour envoyer le roundtrip à
+ la reception du pong */
};
/* flag pour le debug en cas de Filter de regexp */
@@ -181,6 +191,10 @@ static void *application_bind_data = NULL;
static IvyDieCallback application_die_callback;
static void *application_die_user_data = NULL;
+/* callback appele sur reception d'une trame PONG */
+static IvyPongCallback application_pong_callback = NULL;
+
+
/* liste des messages a recevoir */
static MsgRcvPtr msg_recv = NULL;
@@ -713,9 +727,28 @@ static void Receive( Client client, const void *data, char *line )
case Pong:
TRACE("Pong Message\n");
- printf("Receive unhandled Pong message (ivy-c not able to send ping)\n");
+ if (application_pong_callback != NULL) {
+ if (timerisset (&(clnt->ping_timestamp.ts))) {
+ struct timeval now, diff;
+ int roundTripOrTimout;
+ gettimeofday (&now, NULL);
+ timersub (&now, &(clnt->ping_timestamp.ts), &diff);
+ roundTripOrTimout = (MIN(diff.tv_sec, 2000) *1000000) + (diff.tv_usec);
+ timerclear (&(clnt->ping_timestamp.ts));
+
+ // if received id is not the last sent id, it means that whe have not
+ // received the pong of previous ping, so we send negative value which mean
+ // this value is a timout
+ if (id != clnt->ping_timestamp.id) {
+ roundTripOrTimout *= -1;
+ }
+ (*application_pong_callback)( clnt, roundTripOrTimout);
+ }
+ } else {
+ fprintf(stderr, "Receive unhandled Pong message (no registered pong callback defined)\n");
+ }
break;
-
+
default:
printf("Receive unhandled message %s\n", line);
break;
@@ -733,6 +766,8 @@ static RWIvyClientPtr SendService( Client client, const char *appname )
clnt->app_port = 0;
clnt->readyToSend = 0;
clnt->ignore_subsequent_msg =0;
+ clnt->ping_timestamp.ts.tv_sec = clnt->ping_timestamp.ts.tv_usec = 0;
+ clnt->ping_timestamp.id=0;
MsgSendTo(clnt, StartRegexp, ApplicationPort, ApplicationName);
IVY_LIST_EACH(msg_recv, msg )
{
@@ -932,6 +967,11 @@ void IvySetBindCallback( IvyBindCallback bind_callback, void *bind_data )
application_bind_data=bind_data;
}
+void IvySetPongCallback( IvyPongCallback pong_callback )
+{
+ application_pong_callback = pong_callback;
+}
+
void IvySetFilter( int argc, const char **argv)
{
IvyBindingSetFilter( argc, argv );
@@ -1326,6 +1366,19 @@ void IvySendDirectMsg(IvyClientPtr app, int id, char *msg )
MsgSendTo( app, DirectMsg, id, msg);
}
+void IvySendPing( IvyClientPtr app)
+{
+ if (application_pong_callback != NULL) {
+ RWIvyClientPtr clnt = (RWIvyClientPtr) app;
+
+ gettimeofday (&(clnt->ping_timestamp.ts), NULL);
+ MsgSendTo( clnt, Ping, ++clnt->ping_timestamp.id, "");
+ } else {
+ fprintf(stderr,"Application: %s useless IvySendPing issued since no pong callback defined\n",
+ IvyGetApplicationName( app ));
+ }
+}
+
void IvySendDieMsg(IvyClientPtr app )
{
MsgSendTo(app, Die, 0, "" );
diff --git a/src/ivy.h b/src/ivy.h
index 50bc301..df6fcc2 100644
--- a/src/ivy.h
+++ b/src/ivy.h
@@ -15,6 +15,7 @@
* copyright notice regarding this software
*/
+
#ifndef IVY_H
#define IVY_H
@@ -50,6 +51,9 @@ typedef void (*IvyBindCallback)( IvyClientPtr app, void *user_data, int id, cons
/* callback appele sur reception de die */
typedef void (*IvyDieCallback)( IvyClientPtr app, void *user_data, int id ) ;
+/* callback appele sur reception de pong */
+typedef void (*IvyPongCallback)( IvyClientPtr app, int round_trip_delay) ;
+
/* callback appele sur reception de messages normaux */
typedef void (*MsgCallback)( IvyClientPtr app, void *user_data, int argc, char **argv ) ;
@@ -77,6 +81,8 @@ void IvyTerminate(void);
void IvySetBindCallback(
IvyBindCallback bind_callback,
void *bind_data );
+void IvySetPongCallback(
+ IvyPongCallback pong_callback );
void IvyStart (const char*);
void IvyStop (void);
@@ -113,6 +119,16 @@ __attribute__((format(printf,1,2))); /* avec sprintf prealable */
void IvyBindDirectMsg( MsgDirectCallback callback, void *user_data);
void IvySendDirectMsg( IvyClientPtr app, int id, char *msg );
+ /* to use ping protocol, you need to bind a callback to pong with IvySetPongCallback
+ prior to sending ping
+ When pong is received, your supplied callback will be called with an int argument which is :
+ ° if positive value : the round trip time in micro seconds
+ ° if negative value : the timout of the previous ping (for the same application)
+ which has not yet been answered
+ see ivyprobe.c to see a simple example of usage
+*/
+void IvySendPing( IvyClientPtr app);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/version.h b/src/version.h
index 8288a6b..a75a7fa 100644
--- a/src/version.h
+++ b/src/version.h
@@ -26,4 +26,4 @@
*
*/
#define IVYMAJOR_VERSION 3
-#define IVYMINOR_VERSION 13
+#define IVYMINOR_VERSION 14