diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-08-30 12:47:41 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-08-30 12:47:41 +0000 |
commit | 1fda0ae02a745bc47b830482ae3224320f931497 (patch) | |
tree | d590105b98abfabf41c1f4bb320a804dbcebfaae /src | |
parent | 10f3c4a353c9b19c44ae22acf2bdea7ac0a2f01b (diff) | |
download | gnunet-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.c | 64 |
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 | ||
624 | static void | ||
625 | timeout_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, | |||
1000 | void | 1036 | void |
1001 | GNUNET_MESH_notify_transmit_ready_cancel (struct GNUNET_MESH_TransmitHandle *th) | 1037 | GNUNET_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 | ||