[Top][All Lists]
[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;
+ }
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r16638 - gnunet/src/mesh,
gnunet <=