aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-08-30 12:47:41 +0000
committerChristian Grothoff <christian@grothoff.org>2011-08-30 12:47:41 +0000
commit1fda0ae02a745bc47b830482ae3224320f931497 (patch)
treed590105b98abfabf41c1f4bb320a804dbcebfaae /src
parent10f3c4a353c9b19c44ae22acf2bdea7ac0a2f01b (diff)
downloadgnunet-1fda0ae02a745bc47b830482ae3224320f931497.tar.gz
gnunet-1fda0ae02a745bc47b830482ae3224320f931497.zip
timeout support, handle empty queue due to cancel/timeout
Diffstat (limited to 'src')
-rw-r--r--src/mesh/mesh_api_new.c64
1 files changed, 56 insertions, 8 deletions
diff --git a/src/mesh/mesh_api_new.c b/src/mesh/mesh_api_new.c
index b0b8794d8..83ddc8659 100644
--- a/src/mesh/mesh_api_new.c
+++ b/src/mesh/mesh_api_new.c
@@ -96,12 +96,6 @@ struct GNUNET_MESH_TransmitHandle
96 * Closure for 'notify' 96 * Closure for 'notify'
97 */ 97 */
98 void *notify_cls; 98 void *notify_cls;
99
100 /**
101 * Priority of the message. The queue is sorted by priority,
102 * control messages have the maximum priority (UINT32_MAX).
103 */
104 uint32_t priority;
105 99
106 /** 100 /**
107 * How long is this message valid. Once the timeout has been 101 * How long is this message valid. Once the timeout has been
@@ -110,6 +104,17 @@ struct GNUNET_MESH_TransmitHandle
110 * function should be called with 'buf' NULL and size 0. 104 * function should be called with 'buf' NULL and size 0.
111 */ 105 */
112 struct GNUNET_TIME_Absolute timeout; 106 struct GNUNET_TIME_Absolute timeout;
107
108 /**
109 * Task triggering a timeout, can be NO_TASK if the timeout is FOREVER.
110 */
111 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
112
113 /**
114 * Priority of the message. The queue is sorted by priority,
115 * control messages have the maximum priority (UINT32_MAX).
116 */
117 uint32_t priority;
113 118
114 /** 119 /**
115 * Target of the message, 0 for broadcast. This field 120 * Target of the message, 0 for broadcast. This field
@@ -517,6 +522,7 @@ send_raw (void *cls, size_t size, void *buf)
517 return 0; 522 return 0;
518 } 523 }
519 q = h->queue_head; 524 q = h->queue_head;
525 GNUNET_assert (NULL != q);
520 if (sizeof (struct GNUNET_MessageHeader) > size) 526 if (sizeof (struct GNUNET_MessageHeader) > size)
521 { 527 {
522 GNUNET_break (0); 528 GNUNET_break (0);
@@ -589,6 +595,8 @@ send_raw (void *cls, size_t size, void *buf)
589 memcpy (buf, q->data, q->size); 595 memcpy (buf, q->data, q->size);
590 size = q->size; 596 size = q->size;
591 } 597 }
598 if (q->timeout_task != GNUNET_SCHEDULER_NO_TASK)
599 GNUNET_SCHEDULER_cancel (q->timeout_task);
592 GNUNET_CONTAINER_DLL_remove (h->queue_head, h->queue_tail, q); 600 GNUNET_CONTAINER_DLL_remove (h->queue_head, h->queue_tail, q);
593 GNUNET_free (q); 601 GNUNET_free (q);
594 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: size: %u\n", size); 602 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: size: %u\n", size);
@@ -613,6 +621,30 @@ send_raw (void *cls, size_t size, void *buf)
613} 621}
614 622
615 623
624static void
625timeout_transmission (void *cls,
626 const struct GNUNET_SCHEDULER_TaskContext *tc)
627{
628 struct GNUNET_MESH_TransmitHandle *q = cls;
629 struct GNUNET_MESH_Handle *mesh;
630
631 mesh = q->tunnel->mesh;
632 GNUNET_CONTAINER_DLL_remove (mesh->queue_head,
633 mesh->queue_tail,
634 q);
635 if (q->notify != NULL)
636 q->notify (q->notify_cls, 0, NULL); /* signal timeout */
637 GNUNET_free (q);
638 if ( (NULL == mesh->queue_head) &&
639 (NULL != mesh->th) )
640 {
641 /* queue empty, no point in asking for transmission */
642 GNUNET_CLIENT_notify_transmit_ready_cancel (mesh->th);
643 mesh->th = NULL;
644 }
645}
646
647
616/** 648/**
617 * Add a transmit handle to the transmission queue (by priority). 649 * Add a transmit handle to the transmission queue (by priority).
618 * Also manage timeout. 650 * Also manage timeout.
@@ -630,6 +662,10 @@ queue_transmit_handle (struct GNUNET_MESH_Handle *h,
630 while ( (NULL != p) && (q->priority < p->priority) ) 662 while ( (NULL != p) && (q->priority < p->priority) )
631 p = p->next; 663 p = p->next;
632 GNUNET_CONTAINER_DLL_insert_after (h->queue_head, h->queue_tail, p->prev, q); 664 GNUNET_CONTAINER_DLL_insert_after (h->queue_head, h->queue_tail, p->prev, q);
665 if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value != q->timeout.abs_value)
666 q->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (q->timeout),
667 &timeout_transmission,
668 q);
633} 669}
634 670
635 671
@@ -1000,10 +1036,22 @@ GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork,
1000void 1036void
1001GNUNET_MESH_notify_transmit_ready_cancel (struct GNUNET_MESH_TransmitHandle *th) 1037GNUNET_MESH_notify_transmit_ready_cancel (struct GNUNET_MESH_TransmitHandle *th)
1002{ 1038{
1003 GNUNET_CONTAINER_DLL_remove (th->tunnel->mesh->queue_head, 1039 struct GNUNET_MESH_Handle *mesh;
1004 th->tunnel->mesh->queue_tail, 1040
1041 mesh = th->tunnel->mesh;
1042 if (q->timeout_task != GNUNET_SCHEDULER_NO_TASK)
1043 GNUNET_SCHEDULER_cancel (q->timeout_task);
1044 GNUNET_CONTAINER_DLL_remove (mesh->queue_head,
1045 mesh->queue_tail,
1005 th); 1046 th);
1006 GNUNET_free (th); 1047 GNUNET_free (th);
1048 if ( (NULL == mesh->queue_head) &&
1049 (NULL != mesh->th) )
1050 {
1051 /* queue empty, no point in asking for transmission */
1052 GNUNET_CLIENT_notify_transmit_ready_cancel (mesh->th);
1053 mesh->th = NULL;
1054 }
1007} 1055}
1008 1056
1009 1057