changeset 646:cfc8da9264f4

Prepared first part of the changes for #10
author Sebastien Decugis <sdecugis@nict.go.jp>
date Tue, 04 Jan 2011 16:20:50 +0900
parents d9d8f0c1875f
children a13d3dcd2f1b
files freeDiameter/messages.c include/freeDiameter/freeDiameter.h include/freeDiameter/libfreeDiameter.h libfreeDiameter/messages.c
diffstat 4 files changed, 38 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/freeDiameter/messages.c	Tue Jan 04 11:54:19 2011 +0900
+++ b/freeDiameter/messages.c	Tue Jan 04 16:20:50 2011 +0900
@@ -268,7 +268,7 @@
 	
 	/* Save the callback in the message */
 	if (anscb) {
-		CHECK_FCT(  fd_msg_anscb_associate( *pmsg, anscb, data )  );
+		CHECK_FCT(  fd_msg_anscb_associate( *pmsg, anscb, data, NULL /* we should maybe use a safeguard here like 1 hour or so? */ )  );
 	}
 	
 	/* Post the message in the outgoing queue */
@@ -277,6 +277,22 @@
 	return 0;
 }
 
+/* The variation of the same function with a timeout callback */
+int fd_msg_send_timeout ( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data, const struct timespec *timeout )
+{
+	TRACE_ENTRY("%p %p %p", pmsg, anscb, data, timeout);
+	CHECK_PARAMS( pmsg && anscb && timeout );
+	
+	/* Save the callback in the message, with the timeout */
+	CHECK_FCT(  fd_msg_anscb_associate( *pmsg, anscb, data, timeout )  );
+	
+	/* Post the message in the outgoing queue */
+	CHECK_FCT( fd_fifo_post(fd_g_outgoing, pmsg) );
+	
+	return 0;
+}
+
+
 /* Parse a message against our dictionary, and in case of error log and eventually build the error reply -- returns the parsing status */
 int fd_msg_parse_or_error( struct msg ** msg )
 {
--- a/include/freeDiameter/freeDiameter.h	Tue Jan 04 11:54:19 2011 +0900
+++ b/include/freeDiameter/freeDiameter.h	Tue Jan 04 16:20:50 2011 +0900
@@ -370,12 +370,14 @@
 /***************************************/
 
 /*
- * FUNCTION:	fd_msg_send
+ * FUNCTION:	fd_msg_send, fd_msg_send_timeout  
  *
  * PARAMETERS:
  *  pmsg 	: Location of the message to be sent on the network (set to NULL on function return to avoid double deletion).
- *  anscb	: A callback to be called when answer is received, if msg is a request (optional)
+ *  anscb	: A callback to be called when answer is received, if msg is a request (optional for fd_msg_send)
  *  anscb_data	: opaque data to be passed back to the anscb when it is called.
+ *  timeout     : (only for fd_msg_send_timeout) sets the absolute time until when to wait for an answer. Past this time,
+ *                the anscb is called with the request as parameter and the answer will be discarded when received.
  *
  * DESCRIPTION: 
  *   Sends a message on the network. (actually simply queues it in a global queue, to be picked by a daemon's thread)
@@ -398,12 +400,20 @@
  * 
  * If no callback is registered to handle an answer, the message is discarded and an error is logged.
  *
+ *  fd_msg_send_timeout is similar to fd_msg_send, except that it takes an additional argument "timeout" and can be called
+ * only with requests as parameters, and an anscb callback.
+ * If the matching answer or error is received before the timeout date passes, everything occurs as with fd_msg_send. Otherwise,
+ * the request is removed from the queue (meaning the matching answer will be discarded upon reception) and passed to the answcb 
+ * function. This function can easily distinguish between timeout case and answer case by checking if the message received is 
+ * a request. Upon return, if the *msg parameter is not NULL, it is freed (not passed to other callbacks).
+ *
  * RETURN VALUE:
  *  0      	: The message has been queued for sending (sending may fail asynchronously).
  *  EINVAL 	: A parameter is invalid (ex: anscb provided but message is not a request).
  *  ...
  */
 int fd_msg_send ( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data );
+int fd_msg_send_timeout ( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data, const struct timespec *timeout );
 
 /*
  * FUNCTION:	fd_msg_rescode_set
--- a/include/freeDiameter/libfreeDiameter.h	Tue Jan 04 11:54:19 2011 +0900
+++ b/include/freeDiameter/libfreeDiameter.h	Tue Jan 04 16:20:50 2011 +0900
@@ -2134,6 +2134,7 @@
  *  msg		: the answer message
  *  anscb	: the callback to associate with the message
  *  data	: the data to pass to the callback
+ *  timeout     : (optional, use NULL if no timeout) a timeout associated with calling the cb.
  *
  * DESCRIPTION:
  *  Associate or retrieve a callback with an answer message.
@@ -2143,7 +2144,7 @@
  *  0 	  : ok
  *  EINVAL: a parameter is invalid
  */
-int fd_msg_anscb_associate( struct msg * msg, void ( *anscb)(void *, struct msg **), void  * data );
+int fd_msg_anscb_associate( struct msg * msg, void ( *anscb)(void *, struct msg **), void  * data, const struct timespec *timeout );
 int fd_msg_anscb_get      ( struct msg * msg, void (**anscb)(void *, struct msg **), void ** data );
 
 /*
--- a/libfreeDiameter/messages.c	Tue Jan 04 11:54:19 2011 +0900
+++ b/libfreeDiameter/messages.c	Tue Jan 04 16:20:50 2011 +0900
@@ -123,6 +123,7 @@
 	struct {
 			void (*fct)(void *, struct msg **);
 			void * data;
+			struct timespec timeout;
 		}		 msg_cb;		/* Callback to be called when an answer is received, if not NULL */
 	char *			 msg_src_id;		/* Diameter Id of the peer this message was received from. This string is malloc'd and must be freed */
 };
@@ -903,7 +904,7 @@
 }
 
 /* Associate / get answer callbacks */
-int fd_msg_anscb_associate( struct msg * msg, void ( *anscb)(void *, struct msg **), void  * data )
+int fd_msg_anscb_associate( struct msg * msg, void ( *anscb)(void *, struct msg **), void  * data, const struct timespec *timeout )
 {
 	TRACE_ENTRY("%p %p %p", msg, anscb, data);
 	
@@ -915,6 +916,11 @@
 	/* Associate callback and data with the message, if any */
 	msg->msg_cb.fct = anscb;
 	msg->msg_cb.data = data;
+	if (timeout) {
+		memcpy(&msg->msg_cb.timeout, timeout, sizeof(struct timespec));
+	} else {
+		memset(&msg->msg_cb.timeout, 0, sizeof(struct timespec)); /* clear the area */
+	}
 	
 	return 0;
 }	
"Welcome to our mercurial repository"