diff options
Diffstat (limited to 'src/cadet/gnunet-service-cadet_peer.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_peer.c | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/src/cadet/gnunet-service-cadet_peer.c b/src/cadet/gnunet-service-cadet_peer.c index 71c7c67d0..c4e2c0ccf 100644 --- a/src/cadet/gnunet-service-cadet_peer.c +++ b/src/cadet/gnunet-service-cadet_peer.c | |||
@@ -532,32 +532,49 @@ GCP_set_mq (struct CadetPeer *cp, | |||
532 | GCP_2s (cp), | 532 | GCP_2s (cp), |
533 | mq); | 533 | mq); |
534 | cp->core_mq = mq; | 534 | cp->core_mq = mq; |
535 | for (struct GCP_MessageQueueManager *mqm = cp->mqm_head, *next; | 535 | /* Since these callbacks can remove any items from this list, we must take a |
536 | * snapshot and then test each one to see if it's still in the list. */ | ||
537 | int count = 0; | ||
538 | for (struct GCP_MessageQueueManager *mqm = cp->mqm_head; | ||
536 | NULL != mqm; | 539 | NULL != mqm; |
537 | mqm = next) | 540 | mqm = mqm->next) |
541 | ++count; | ||
542 | struct GCP_MessageQueueManager *mqms[count]; | ||
543 | int i = 0; | ||
544 | for (struct GCP_MessageQueueManager *mqm = cp->mqm_head; | ||
545 | NULL != mqm; | ||
546 | mqm = mqm->next) | ||
547 | mqms[i++] = mqm; | ||
548 | for (i = 0; i < count; ++i) | ||
538 | { | 549 | { |
539 | /* Save next pointer in case mqm gets freed by the callback */ | 550 | for (struct GCP_MessageQueueManager *mqm = cp->mqm_head; |
540 | next = mqm->next; | 551 | NULL != mqm; |
541 | if (NULL == mq) | 552 | mqm = mqm->next) |
542 | { | 553 | { |
543 | if (NULL != mqm->env) | 554 | if (mqms[i] != mqm) |
555 | continue; | ||
556 | if (NULL == mq) | ||
544 | { | 557 | { |
545 | GNUNET_MQ_discard (mqm->env); | 558 | if (NULL != mqm->env) |
546 | mqm->env = NULL; | 559 | { |
547 | mqm->cb (mqm->cb_cls, | 560 | GNUNET_MQ_discard (mqm->env); |
548 | GNUNET_SYSERR); | 561 | mqm->env = NULL; |
562 | mqm->cb (mqm->cb_cls, | ||
563 | GNUNET_SYSERR); | ||
564 | } | ||
565 | else | ||
566 | { | ||
567 | mqm->cb (mqm->cb_cls, | ||
568 | GNUNET_NO); | ||
569 | } | ||
549 | } | 570 | } |
550 | else | 571 | else |
551 | { | 572 | { |
573 | GNUNET_assert (NULL == mqm->env); | ||
552 | mqm->cb (mqm->cb_cls, | 574 | mqm->cb (mqm->cb_cls, |
553 | GNUNET_NO); | 575 | GNUNET_YES); |
554 | } | 576 | } |
555 | } | 577 | break; |
556 | else | ||
557 | { | ||
558 | GNUNET_assert (NULL == mqm->env); | ||
559 | mqm->cb (mqm->cb_cls, | ||
560 | GNUNET_YES); | ||
561 | } | 578 | } |
562 | } | 579 | } |
563 | if ( (NULL != mq) || | 580 | if ( (NULL != mq) || |