gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r26458 - gnunet/src/dv


From: gnunet
Subject: [GNUnet-SVN] r26458 - gnunet/src/dv
Date: Fri, 15 Mar 2013 13:57:54 +0100

Author: grothoff
Date: 2013-03-15 13:57:54 +0100 (Fri, 15 Mar 2013)
New Revision: 26458

Modified:
   gnunet/src/dv/plugin_transport_dv.c
Log:
-draft for DV plugin

Modified: gnunet/src/dv/plugin_transport_dv.c
===================================================================
--- gnunet/src/dv/plugin_transport_dv.c 2013-03-15 12:40:50 UTC (rev 26457)
+++ gnunet/src/dv/plugin_transport_dv.c 2013-03-15 12:57:54 UTC (rev 26458)
@@ -45,20 +45,20 @@
 
 
 /**
- * Session handle for connections.
+ * An active request for transmission via DV.
  */
-struct Session
+struct PendingRequest
 {
 
   /**
-   * Mandatory session header.
+   * This is a DLL.
    */
-  struct SessionHeader header;
+  struct PendingRequest *next;
 
   /**
-   * Pointer to the global plugin struct.
+   * This is a DLL.
    */
-  struct Plugin *plugin;
+  struct PendingRequest *prev;
 
   /**
    * Continuation function to call once the transmission buffer
@@ -73,6 +73,45 @@
   void *transmit_cont_cls;
 
   /**
+   * Transmission handle from DV client library.
+   */
+  struct GNUNET_DV_TransmitHandle *th;
+
+  /**
+   * Session of this request.
+   */
+  struct Session *session;
+
+};
+
+
+/**
+ * Session handle for connections.
+ */
+struct Session
+{
+
+  /**
+   * Mandatory session header.
+   */
+  struct SessionHeader header;
+
+  /**
+   * Pointer to the global plugin struct.
+   */
+  struct Plugin *plugin;
+
+  /**
+   * Head of pending requests.
+   */
+  struct PendingRequest *pr_head;
+
+  /**
+   * Tail of pending requests.
+   */
+  struct PendingRequest *pr_tail;
+
+  /**
    * To whom are we talking to.
    */
   struct GNUNET_PeerIdentity sender;
@@ -121,6 +160,18 @@
 
 
 /**
+ * Notify transport service about the change in distance.
+ *
+ * @param session session where the distance changed
+ */
+static void
+notify_distance_change (struct Session *session)
+{
+  GNUNET_break (0); // FIXME: need extended plugin API!
+}
+
+
+/**
  * Handler for messages received from the DV service.
  *
  * @param cls closure with the plugin
@@ -177,7 +228,7 @@
     GNUNET_break (0);
     session->distance = distance;
     if (GNUNET_YES == session->active)
-      GNUNET_break (0); // FIXME: notify transport about distance change
+      notify_distance_change (session);
     return; /* nothing to do */  
   }
   session = GNUNET_malloc (sizeof (struct Session));
@@ -216,11 +267,47 @@
   }
   session->distance = distance;
   if (GNUNET_YES == session->active)
-    GNUNET_break (0); // FIXME: notify transport about distance change
+    notify_distance_change (session);
 }
 
 
 /**
+ * Release session object and clean up associated resources.
+ *
+ * @param session session to clean up
+ */
+static void
+free_session (struct Session *session)
+{
+  struct Plugin *plugin = session->plugin;
+  struct PendingRequest *pr;
+
+  GNUNET_assert (GNUNET_YES ==
+                GNUNET_CONTAINER_multihashmap_remove (plugin->sessions,
+                                                      
&session->sender.hashPubKey,
+                                                      session));
+  if (GNUNET_YES == session->active)
+    plugin->env->session_end (plugin->env->cls,
+                             &session->sender,
+                             session);
+  while (NULL != (pr = session->pr_head))
+  {
+    GNUNET_CONTAINER_DLL_remove (session->pr_head,
+                                session->pr_tail,
+                                pr);
+    GNUNET_DV_send_cancel (pr->th);
+    pr->th = NULL;
+    if (NULL != pr->transmit_cont)
+      pr->transmit_cont (pr->transmit_cont_cls,
+                        &session->sender,
+                        GNUNET_SYSERR, 0, 0);
+    GNUNET_free (pr);
+  }
+  GNUNET_free (session);
+}
+
+
+/**
  * Function called if DV is no longer able to talk to a peer.
  *
  * @param cls closure with 'struct Plugin'
@@ -236,12 +323,38 @@
   session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions,
                                               &peer->hashPubKey);
   if (NULL == session)    
-    return; /* nothing to do */  
-  GNUNET_break (0); // FIXME!
+    return; /* nothing to do */
+  free_session (session);
 }
 
 
 /**
+ * Function called once the delivery of a message has been successful.
+ * Clean up the pending request, and call continuations.
+ *
+ * @param cls closure
+ * @param ok GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+static void
+send_finished (void *cls,
+              int ok)
+{
+  struct PendingRequest *pr = cls;
+  struct Session *session = pr->session;
+
+  pr->th = NULL;
+  GNUNET_CONTAINER_DLL_remove (session->pr_head,
+                              session->pr_tail,
+                              pr);
+  if (NULL != pr->transmit_cont)
+    pr->transmit_cont (pr->transmit_cont_cls,
+                      &session->sender,
+                      ok, 0, 0);
+  GNUNET_free (pr);
+}
+
+
+/**
  * Function that can be used by the transport service to transmit
  * a message using the plugin.
  *
@@ -267,10 +380,24 @@
                 struct GNUNET_TIME_Relative timeout, 
                 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
 {
-  int ret = -1;
+  struct PendingRequest *pr;
+  const struct GNUNET_MessageHeader *msg;
 
-  GNUNET_break (0); // FIXME!
-  return ret;
+  msg = (const struct GNUNET_MessageHeader *) msgbuf;
+  GNUNET_assert (ntohs (msg->size) == msgbuf_size); // API will change...
+  pr = GNUNET_malloc (sizeof (struct PendingRequest));
+  pr->transmit_cont = cont;
+  pr->transmit_cont_cls = cont_cls;
+  pr->session = session;
+  GNUNET_CONTAINER_DLL_insert_tail (session->pr_head,
+                                   session->pr_tail,
+                                   pr);
+  pr->th = GNUNET_DV_send (session->plugin->dvh,
+                          &session->sender,
+                          msg,
+                          &send_finished,
+                          pr);
+  return 0; /* DV */
 }
 
 
@@ -287,13 +414,25 @@
 {
   struct Plugin *plugin = cls;
   struct Session *session;
+  struct PendingRequest *pr;
 
   session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions,
                                               &target->hashPubKey);
   if (NULL == session)    
     return; /* nothing to do */  
-  session->transmit_cont = NULL;
-  session->transmit_cont_cls = NULL;
+  while (NULL != (pr = session->pr_head))
+  {
+    GNUNET_CONTAINER_DLL_remove (session->pr_head,
+                                session->pr_tail,
+                                pr);
+    GNUNET_DV_send_cancel (pr->th);
+    pr->th = NULL;
+    if (NULL != pr->transmit_cont)
+      pr->transmit_cont (pr->transmit_cont_cls,
+                        &session->sender,
+                        GNUNET_SYSERR, 0, 0);
+    GNUNET_free (pr);
+  }
   session->active = GNUNET_NO;
 }
 
@@ -481,8 +620,7 @@
 {
   struct Session *session = value;
 
-  // FIXME: still call transmit_cont's here!?
-  GNUNET_free (session);
+  free_session (session);
   return GNUNET_OK;
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]