aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-05-27 17:25:19 +0000
committerChristian Grothoff <christian@grothoff.org>2011-05-27 17:25:19 +0000
commitb8edc262dae8adf7d616830466968ab8e3367a52 (patch)
treeb5ec653bfeff72033dfe6c548d48c0cd16fbcafb /src/core
parent07e4a25f1e71d7e3421d8a9d32227d862b0afb42 (diff)
downloadgnunet-b8edc262dae8adf7d616830466968ab8e3367a52.tar.gz
gnunet-b8edc262dae8adf7d616830466968ab8e3367a52.zip
avoid direct call of notification -- except on error
Diffstat (limited to 'src/core')
-rw-r--r--src/core/core_api.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/src/core/core_api.c b/src/core/core_api.c
index 4f4337061..1c79b0519 100644
--- a/src/core/core_api.c
+++ b/src/core/core_api.c
@@ -102,6 +102,11 @@ struct PeerRecord
102 GNUNET_SCHEDULER_TaskIdentifier timeout_task; 102 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
103 103
104 /** 104 /**
105 * ID of task to run 'next_request_transmission'.
106 */
107 GNUNET_SCHEDULER_TaskIdentifier ntr_task;
108
109 /**
105 * Current size of the queue of pending requests. 110 * Current size of the queue of pending requests.
106 */ 111 */
107 unsigned int queue_size; 112 unsigned int queue_size;
@@ -440,6 +445,11 @@ disconnect_and_free_peer_entry (void *cls,
440 GNUNET_SCHEDULER_cancel (pr->timeout_task); 445 GNUNET_SCHEDULER_cancel (pr->timeout_task);
441 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK; 446 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
442 } 447 }
448 if (pr->ntr_task != GNUNET_SCHEDULER_NO_TASK)
449 {
450 GNUNET_SCHEDULER_cancel (pr->ntr_task);
451 pr->ntr_task = GNUNET_SCHEDULER_NO_TASK;
452 }
443 GNUNET_assert (pr->queue_size == 0); 453 GNUNET_assert (pr->queue_size == 0);
444 if ( (pr->prev != NULL) || 454 if ( (pr->prev != NULL) ||
445 (pr->next != NULL) || 455 (pr->next != NULL) ||
@@ -459,6 +469,7 @@ disconnect_and_free_peer_entry (void *cls,
459 GNUNET_assert (pr->ch = h); 469 GNUNET_assert (pr->ch = h);
460 GNUNET_assert (pr->queue_size == 0); 470 GNUNET_assert (pr->queue_size == 0);
461 GNUNET_assert (pr->timeout_task == GNUNET_SCHEDULER_NO_TASK); 471 GNUNET_assert (pr->timeout_task == GNUNET_SCHEDULER_NO_TASK);
472 GNUNET_assert (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK);
462 GNUNET_free (pr); 473 GNUNET_free (pr);
463 return GNUNET_YES; 474 return GNUNET_YES;
464} 475}
@@ -734,6 +745,7 @@ transmit_message (void *cls,
734 GNUNET_i2s (&pr->peer), 745 GNUNET_i2s (&pr->peer),
735 ret); 746 ret);
736#endif 747#endif
748 GNUNET_free (th);
737 if (0 == ret) 749 if (0 == ret)
738 { 750 {
739#if DEBUG_CORE 751#if DEBUG_CORE
@@ -743,7 +755,6 @@ transmit_message (void *cls,
743#endif 755#endif
744 /* client decided to send nothing! */ 756 /* client decided to send nothing! */
745 request_next_transmission (pr); 757 request_next_transmission (pr);
746 GNUNET_free (th);
747 return 0; 758 return 0;
748 } 759 }
749#if DEBUG_CORE 760#if DEBUG_CORE
@@ -756,13 +767,11 @@ transmit_message (void *cls,
756 { 767 {
757 GNUNET_break (0); 768 GNUNET_break (0);
758 request_next_transmission (pr); 769 request_next_transmission (pr);
759 GNUNET_free (th);
760 return 0; 770 return 0;
761 } 771 }
762 ret += sizeof (struct SendMessage); 772 ret += sizeof (struct SendMessage);
763 sm->header.size = htons (ret); 773 sm->header.size = htons (ret);
764 GNUNET_assert (ret <= size); 774 GNUNET_assert (ret <= size);
765 GNUNET_free (th);
766 request_next_transmission (pr); 775 request_next_transmission (pr);
767 return ret; 776 return ret;
768 } 777 }
@@ -1507,6 +1516,23 @@ GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
1507 1516
1508 1517
1509/** 1518/**
1519 * Task that calls 'request_next_transmission'.
1520 *
1521 * @param cls the 'struct PeerRecord*'
1522 * @param tc scheduler context
1523 */
1524static void
1525run_request_next_transmission (void *cls,
1526 const struct GNUNET_SCHEDULER_TaskContext *tc)
1527{
1528 struct PeerRecord *pr = cls;
1529
1530 pr->ntr_task = GNUNET_SCHEDULER_NO_TASK;
1531 request_next_transmission (pr);
1532}
1533
1534
1535/**
1510 * Ask the core to call "notify" once it is ready to transmit the 1536 * Ask the core to call "notify" once it is ready to transmit the
1511 * given number of bytes to the specified "target". Must only be 1537 * given number of bytes to the specified "target". Must only be
1512 * called after a connection to the respective peer has been 1538 * called after a connection to the respective peer has been
@@ -1634,8 +1660,9 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle,
1634 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1660 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1635 "Transmission request added to queue\n"); 1661 "Transmission request added to queue\n");
1636#endif 1662#endif
1637 if (pr->pending_head == th) 1663 if ( (pr->pending_head == th) &&
1638 request_next_transmission (pr); 1664 (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK) )
1665 pr->ntr_task = GNUNET_SCHEDULER_add_now (&run_request_next_transmission, pr);
1639 return th; 1666 return th;
1640} 1667}
1641 1668
@@ -1652,7 +1679,7 @@ GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle
1652 struct PeerRecord *pr = th->peer; 1679 struct PeerRecord *pr = th->peer;
1653 struct GNUNET_CORE_Handle *h = pr->ch; 1680 struct GNUNET_CORE_Handle *h = pr->ch;
1654 int was_head; 1681 int was_head;
1655 1682
1656 was_head = (pr->pending_head == th); 1683 was_head = (pr->pending_head == th);
1657 GNUNET_CONTAINER_DLL_remove (pr->pending_head, 1684 GNUNET_CONTAINER_DLL_remove (pr->pending_head,
1658 pr->pending_tail, 1685 pr->pending_tail,