gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r16638 - gnunet/src/mesh


From: gnunet
Subject: [GNUnet-SVN] r16638 - gnunet/src/mesh
Date: Tue, 30 Aug 2011 14:47:41 +0200

Author: grothoff
Date: 2011-08-30 14:47:41 +0200 (Tue, 30 Aug 2011)
New Revision: 16638

Modified:
   gnunet/src/mesh/mesh_api_new.c
Log:
timeout support, handle empty queue due to cancel/timeout

Modified: gnunet/src/mesh/mesh_api_new.c
===================================================================
--- gnunet/src/mesh/mesh_api_new.c      2011-08-30 12:34:27 UTC (rev 16637)
+++ gnunet/src/mesh/mesh_api_new.c      2011-08-30 12:47:41 UTC (rev 16638)
@@ -96,12 +96,6 @@
    * Closure for 'notify'
    */
   void *notify_cls;
-
-  /**
-   * Priority of the message.  The queue is sorted by priority,
-   * control messages have the maximum priority (UINT32_MAX).
-   */
-  uint32_t priority;
   
   /**
    * How long is this message valid.  Once the timeout has been
@@ -110,6 +104,17 @@
    * function should be called with 'buf' NULL and size 0.
    */
   struct GNUNET_TIME_Absolute timeout;
+
+  /**
+   * Task triggering a timeout, can be NO_TASK if the timeout is FOREVER.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+
+  /**
+   * Priority of the message.  The queue is sorted by priority,
+   * control messages have the maximum priority (UINT32_MAX).
+   */
+  uint32_t priority;
  
   /**
    * Target of the message, 0 for broadcast.  This field
@@ -517,6 +522,7 @@
     return 0;
   }
   q = h->queue_head;
+  GNUNET_assert (NULL != q);
   if (sizeof (struct GNUNET_MessageHeader) > size)
   {
     GNUNET_break (0);
@@ -589,6 +595,8 @@
       memcpy (buf, q->data, q->size);
       size = q->size;
     }
+  if (q->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+    GNUNET_SCHEDULER_cancel (q->timeout_task);
   GNUNET_CONTAINER_DLL_remove (h->queue_head, h->queue_tail, q);
   GNUNET_free (q);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh:   size: %u\n", size);
@@ -613,6 +621,30 @@
 }
 
 
+static void
+timeout_transmission (void *cls,
+                     const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_MESH_TransmitHandle *q = cls;
+  struct GNUNET_MESH_Handle *mesh;
+  
+  mesh = q->tunnel->mesh;
+  GNUNET_CONTAINER_DLL_remove (mesh->queue_head, 
+                              mesh->queue_tail,
+                               q);
+  if (q->notify != NULL)
+    q->notify (q->notify_cls, 0, NULL); /* signal timeout */
+  GNUNET_free (q);    
+  if ( (NULL == mesh->queue_head) &&
+       (NULL != mesh->th) )
+    {
+      /* queue empty, no point in asking for transmission */
+      GNUNET_CLIENT_notify_transmit_ready_cancel (mesh->th);
+      mesh->th = NULL;
+    }    
+}
+
+
 /**
  * Add a transmit handle to the transmission queue (by priority).
  * Also manage timeout.
@@ -630,6 +662,10 @@
   while ( (NULL != p) && (q->priority < p->priority) )
     p = p->next;
   GNUNET_CONTAINER_DLL_insert_after (h->queue_head, h->queue_tail, p->prev, q);
+  if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value != q->timeout.abs_value)
+    q->timeout_task = GNUNET_SCHEDULER_add_delayed 
(GNUNET_TIME_absolute_get_remaining (q->timeout),
+                                                   &timeout_transmission,
+                                                   q);
 }
 
 
@@ -1000,10 +1036,22 @@
 void
 GNUNET_MESH_notify_transmit_ready_cancel (struct GNUNET_MESH_TransmitHandle 
*th)
 {
-  GNUNET_CONTAINER_DLL_remove (th->tunnel->mesh->queue_head, 
-                              th->tunnel->mesh->queue_tail,
+  struct GNUNET_MESH_Handle *mesh;
+  
+  mesh = th->tunnel->mesh;
+  if (q->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+    GNUNET_SCHEDULER_cancel (q->timeout_task);
+  GNUNET_CONTAINER_DLL_remove (mesh->queue_head, 
+                              mesh->queue_tail,
                                th);
   GNUNET_free (th);
+  if ( (NULL == mesh->queue_head) &&
+       (NULL != mesh->th) )
+    {
+      /* queue empty, no point in asking for transmission */
+      GNUNET_CLIENT_notify_transmit_ready_cancel (mesh->th);
+      mesh->th = NULL;
+    }    
 }
 
 




reply via email to

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