diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2013-09-02 14:25:54 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2013-09-02 14:25:54 +0000 |
commit | 6ea7ba4bfcd11cbfc0b828f12d881f983d277bc7 (patch) | |
tree | 1de1beff9a9c31428c01e2cb896a0e82fe1bd274 /src/testbed/gnunet-service-testbed_barriers.c | |
parent | c9b0b7850190a2deec71bc8029a8db58ad809fd5 (diff) | |
download | gnunet-6ea7ba4bfcd11cbfc0b828f12d881f983d277bc7.tar.gz gnunet-6ea7ba4bfcd11cbfc0b828f12d881f983d277bc7.zip |
- more barrier code
Diffstat (limited to 'src/testbed/gnunet-service-testbed_barriers.c')
-rw-r--r-- | src/testbed/gnunet-service-testbed_barriers.c | 113 |
1 files changed, 86 insertions, 27 deletions
diff --git a/src/testbed/gnunet-service-testbed_barriers.c b/src/testbed/gnunet-service-testbed_barriers.c index e0d0e2f18..0a4c84808 100644 --- a/src/testbed/gnunet-service-testbed_barriers.c +++ b/src/testbed/gnunet-service-testbed_barriers.c | |||
@@ -25,6 +25,8 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include "gnunet-service-testbed.h" | 27 | #include "gnunet-service-testbed.h" |
28 | #include "gnunet-service-testbed_barriers.h" | ||
29 | |||
28 | 30 | ||
29 | /** | 31 | /** |
30 | * timeout for outgoing message transmissions in seconds | 32 | * timeout for outgoing message transmissions in seconds |
@@ -320,8 +322,7 @@ remove_barrier (struct Barrier *barrier) | |||
320 | &barrier->hash, | 322 | &barrier->hash, |
321 | barrier)); | 323 | barrier)); |
322 | GNUNET_free (barrier->name); | 324 | GNUNET_free (barrier->name); |
323 | if (NULL != barrier->client) | 325 | GNUNET_SERVER_client_drop (barrier->client); |
324 | GNUNET_SERVER_client_drop (barrier->client); | ||
325 | GNUNET_free (barrier); | 326 | GNUNET_free (barrier); |
326 | } | 327 | } |
327 | 328 | ||
@@ -346,34 +347,52 @@ cancel_wrappers (struct Barrier *barrier) | |||
346 | 347 | ||
347 | 348 | ||
348 | /** | 349 | /** |
349 | * Sends a barrier failed message | 350 | * Send a status message about a barrier to the given client |
350 | * | 351 | * |
351 | * @param barrier the corresponding barrier | 352 | * @param client the client to send the message to |
353 | * @param name the barrier name | ||
352 | * @param status the status of the barrier | 354 | * @param status the status of the barrier |
353 | * @param emsg the error message; should be non-NULL for | 355 | * @param emsg the error message; should be non-NULL for |
354 | * status=BARRIER_STATUS_ERROR | 356 | * status=BARRIER_STATUS_ERROR |
355 | */ | 357 | */ |
356 | static void | 358 | static void |
357 | send_barrier_status_msg (struct Barrier *barrier, | 359 | send_client_status_msg (struct GNUNET_SERVER_Client *client, |
358 | enum GNUNET_TESTBED_BarrierStatus status, | 360 | const char *name, |
359 | const char *emsg) | 361 | enum GNUNET_TESTBED_BarrierStatus status, |
362 | const char *emsg) | ||
360 | { | 363 | { |
361 | struct GNUNET_TESTBED_BarrierStatusMsg *msg; | 364 | struct GNUNET_TESTBED_BarrierStatusMsg *msg; |
362 | size_t name_len; | 365 | size_t name_len; |
363 | uint16_t msize; | 366 | uint16_t msize; |
364 | 367 | ||
365 | GNUNET_assert ((NULL == emsg) || (BARRIER_STATUS_ERROR == status)); | 368 | GNUNET_assert ((NULL == emsg) || (BARRIER_STATUS_ERROR == status)); |
366 | name_len = strlen (barrier->name) + 1; | 369 | name_len = strlen (name) + 1; |
367 | msize = sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) | 370 | msize = sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) |
368 | + name_len | 371 | + name_len |
369 | + (NULL == emsg) ? 0 : strlen (emsg) + 1; | 372 | + (NULL == emsg) ? 0 : strlen (emsg) + 1; |
370 | msg = GNUNET_malloc (msize); | 373 | msg = GNUNET_malloc (msize); |
371 | msg->status = htons (status); | 374 | msg->status = htons (status); |
372 | msg->name_len = htons (name_len); | 375 | msg->name_len = htons ((uint16_t) name_len); |
373 | (void) memcpy (msg->data, barrier->name, name_len); | 376 | (void) memcpy (msg->data, name, name_len); |
374 | if (NULL != emsg) | 377 | if (NULL != emsg) |
375 | (void) memcpy (msg->data + name_len, emsg, strlen (emsg) + 1); | 378 | (void) memcpy (msg->data + name_len, emsg, strlen (emsg) + 1); |
376 | GST_queue_message (barrier->client, &msg->header); | 379 | GST_queue_message (client, &msg->header); |
380 | } | ||
381 | |||
382 | |||
383 | /** | ||
384 | * Sends a barrier failed message | ||
385 | * | ||
386 | * @param barrier the corresponding barrier | ||
387 | * @param emsg the error message; should be non-NULL for | ||
388 | * status=BARRIER_STATUS_ERROR | ||
389 | */ | ||
390 | static void | ||
391 | send_barrier_status_msg (struct Barrier *barrier, const char *emsg) | ||
392 | { | ||
393 | GNUNET_assert (0 != barrier->status); | ||
394 | send_client_status_msg (barrier->client, barrier->name, | ||
395 | barrier->status, emsg); | ||
377 | } | 396 | } |
378 | 397 | ||
379 | 398 | ||
@@ -501,7 +520,6 @@ disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client) | |||
501 | GNUNET_CONTAINER_DLL_remove (barrier->head, barrier->tail, client_ctx); | 520 | GNUNET_CONTAINER_DLL_remove (barrier->head, barrier->tail, client_ctx); |
502 | if (NULL != client_ctx->tx) | 521 | if (NULL != client_ctx->tx) |
503 | GNUNET_SERVER_notify_transmit_ready_cancel (client_ctx->tx); | 522 | GNUNET_SERVER_notify_transmit_ready_cancel (client_ctx->tx); |
504 | |||
505 | } | 523 | } |
506 | 524 | ||
507 | 525 | ||
@@ -573,21 +591,38 @@ wbarrier_status_cb (void *cls, const char *name, | |||
573 | cancel_wrappers (barrier); | 591 | cancel_wrappers (barrier); |
574 | if (NULL == emsg) | 592 | if (NULL == emsg) |
575 | emsg = "Initialisation failed at a sub-controller"; | 593 | emsg = "Initialisation failed at a sub-controller"; |
576 | send_barrier_status_msg (barrier, BARRIER_STATUS_ERROR, emsg); | 594 | barrier->status = BARRIER_STATUS_ERROR; |
595 | send_barrier_status_msg (barrier, emsg); | ||
577 | return; | 596 | return; |
578 | } | 597 | } |
579 | switch (status) | 598 | switch (status) |
580 | { | 599 | { |
581 | case BARRIER_STATUS_CROSSED: | 600 | case BARRIER_STATUS_CROSSED: |
601 | if (BARRIER_STATUS_INITIALISED != barrier->status) | ||
602 | { | ||
603 | GNUNET_break_op (0); | ||
604 | return; | ||
605 | } | ||
582 | barrier->num_wbarriers_reached++; | 606 | barrier->num_wbarriers_reached++; |
583 | if ((barrier->num_wbarriers_reached == barrier->num_wbarriers) | 607 | if ((barrier->num_wbarriers_reached == barrier->num_wbarriers) |
584 | && (LOCAL_QUORUM_REACHED (barrier))) | 608 | && (LOCAL_QUORUM_REACHED (barrier))) |
585 | send_barrier_status_msg (barrier, BARRIER_STATUS_CROSSED, NULL); | 609 | { |
610 | barrier->status = BARRIER_STATUS_CROSSED; | ||
611 | send_barrier_status_msg (barrier, NULL); | ||
612 | } | ||
586 | break; | 613 | break; |
587 | case BARRIER_STATUS_INITIALISED: | 614 | case BARRIER_STATUS_INITIALISED: |
615 | if (0 != barrier->status) | ||
616 | { | ||
617 | GNUNET_break_op (0); | ||
618 | return; | ||
619 | } | ||
588 | barrier->num_wbarriers_inited++; | 620 | barrier->num_wbarriers_inited++; |
589 | if (barrier->num_wbarriers_inited == barrier->num_wbarriers) | 621 | if (barrier->num_wbarriers_inited == barrier->num_wbarriers) |
590 | send_barrier_status_msg (barrier, BARRIER_STATUS_INITIALISED, NULL); | 622 | { |
623 | barrier->status = BARRIER_STATUS_INITIALISED; | ||
624 | send_barrier_status_msg (barrier, NULL); | ||
625 | } | ||
591 | break; | 626 | break; |
592 | case BARRIER_STATUS_ERROR: | 627 | case BARRIER_STATUS_ERROR: |
593 | GNUNET_assert (0); | 628 | GNUNET_assert (0); |
@@ -611,7 +646,8 @@ fwd_tout_barrier_init (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
611 | barrier->nslaves--; | 646 | barrier->nslaves--; |
612 | barrier->timedout = GNUNET_YES; | 647 | barrier->timedout = GNUNET_YES; |
613 | cancel_wrappers (barrier); | 648 | cancel_wrappers (barrier); |
614 | send_barrier_status_msg (barrier, BARRIER_STATUS_ERROR, | 649 | barrier->status = BARRIER_STATUS_ERROR; |
650 | send_barrier_status_msg (barrier, | ||
615 | "Timedout while propagating barrier initialisation\n"); | 651 | "Timedout while propagating barrier initialisation\n"); |
616 | remove_barrier (barrier); | 652 | remove_barrier (barrier); |
617 | } | 653 | } |
@@ -634,13 +670,12 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client, | |||
634 | const struct GNUNET_MessageHeader *message) | 670 | const struct GNUNET_MessageHeader *message) |
635 | { | 671 | { |
636 | const struct GNUNET_TESTBED_BarrierInit *msg; | 672 | const struct GNUNET_TESTBED_BarrierInit *msg; |
637 | const char *name; | 673 | char *name; |
638 | struct Barrier *barrier; | 674 | struct Barrier *barrier; |
639 | struct Slave *slave; | 675 | struct Slave *slave; |
640 | struct WBarrier *wrapper; | 676 | struct WBarrier *wrapper; |
641 | struct GNUNET_HashCode hash; | 677 | struct GNUNET_HashCode hash; |
642 | size_t name_len; | 678 | size_t name_len; |
643 | uint64_t op_id; | ||
644 | unsigned int cnt; | 679 | unsigned int cnt; |
645 | uint16_t msize; | 680 | uint16_t msize; |
646 | 681 | ||
@@ -664,22 +699,24 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client, | |||
664 | return; | 699 | return; |
665 | } | 700 | } |
666 | msg = (const struct GNUNET_TESTBED_BarrierInit *) message; | 701 | msg = (const struct GNUNET_TESTBED_BarrierInit *) message; |
667 | op_id = GNUNET_ntohll (msg->op_id); | ||
668 | name = msg->name; | ||
669 | name_len = (size_t) msize - sizeof (struct GNUNET_TESTBED_BarrierInit); | 702 | name_len = (size_t) msize - sizeof (struct GNUNET_TESTBED_BarrierInit); |
703 | name = GNUNET_malloc (name_len + 1); | ||
704 | (void) memcpy (name, msg->name, name_len); | ||
705 | name[name_len] = '\0'; | ||
670 | GNUNET_CRYPTO_hash (name, name_len, &hash); | 706 | GNUNET_CRYPTO_hash (name, name_len, &hash); |
671 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (barrier_map, &hash)) | 707 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (barrier_map, &hash)) |
672 | { | 708 | { |
673 | GST_send_operation_fail_msg (client, op_id, "Barrier already initialised"); | 709 | |
710 | send_client_status_msg (client, name, BARRIER_STATUS_ERROR, | ||
711 | "A barrier with the same name already exists"); | ||
712 | GNUNET_free (name); | ||
674 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 713 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
675 | return; | 714 | return; |
676 | } | 715 | } |
677 | barrier = GNUNET_malloc (sizeof (struct Barrier)); | 716 | barrier = GNUNET_malloc (sizeof (struct Barrier)); |
678 | (void) memcpy (&barrier->hash, &hash, sizeof (struct GNUNET_HashCode)); | 717 | (void) memcpy (&barrier->hash, &hash, sizeof (struct GNUNET_HashCode)); |
679 | barrier->quorum = msg->quorum; | 718 | barrier->quorum = msg->quorum; |
680 | barrier->name = GNUNET_malloc (name_len + 1); | 719 | barrier->name = name; |
681 | barrier->name[name_len] = '\0'; | ||
682 | (void) memcpy (barrier->name, name, name_len); | ||
683 | barrier->client = client; | 720 | barrier->client = client; |
684 | GNUNET_SERVER_client_keep (client); | 721 | GNUNET_SERVER_client_keep (client); |
685 | GNUNET_assert (GNUNET_OK == | 722 | GNUNET_assert (GNUNET_OK == |
@@ -697,7 +734,7 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client, | |||
697 | { | 734 | { |
698 | GNUNET_break (0);/* May happen when we are connecting to the controller */ | 735 | GNUNET_break (0);/* May happen when we are connecting to the controller */ |
699 | continue; | 736 | continue; |
700 | } | 737 | } |
701 | wrapper = GNUNET_malloc (sizeof (struct WBarrier)); | 738 | wrapper = GNUNET_malloc (sizeof (struct WBarrier)); |
702 | wrapper->barrier = barrier; | 739 | wrapper->barrier = barrier; |
703 | GNUNET_CONTAINER_DLL_insert_tail (barrier->whead, barrier->wtail, wrapper); | 740 | GNUNET_CONTAINER_DLL_insert_tail (barrier->whead, barrier->wtail, wrapper); |
@@ -708,11 +745,33 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client, | |||
708 | wrapper); | 745 | wrapper); |
709 | } | 746 | } |
710 | if (NULL == barrier->whead) /* No further propagation */ | 747 | if (NULL == barrier->whead) /* No further propagation */ |
711 | send_barrier_status_msg (barrier, BARRIER_STATUS_INITIALISED, NULL); | 748 | { |
712 | else | 749 | barrier->status = BARRIER_STATUS_INITIALISED; |
750 | send_barrier_status_msg (barrier, NULL); | ||
751 | }else | ||
713 | barrier->tout_task = GNUNET_SCHEDULER_add_delayed (MESSAGE_SEND_TIMEOUT (30), | 752 | barrier->tout_task = GNUNET_SCHEDULER_add_delayed (MESSAGE_SEND_TIMEOUT (30), |
714 | &fwd_tout_barrier_init, | 753 | &fwd_tout_barrier_init, |
715 | barrier); | 754 | barrier); |
716 | } | 755 | } |
717 | 756 | ||
757 | |||
758 | /** | ||
759 | * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages. This | ||
760 | * message should always come from a parent controller or the testbed API if we | ||
761 | * are the root controller. | ||
762 | * | ||
763 | * This handler is queued in the main service and will handle the messages sent | ||
764 | * either from the testbed driver or from a high level controller | ||
765 | * | ||
766 | * @param cls NULL | ||
767 | * @param client identification of the client | ||
768 | * @param message the actual message | ||
769 | */ | ||
770 | void | ||
771 | GST_handle_barrier_cancel (void *cls, struct GNUNET_SERVER_Client *client, | ||
772 | const struct GNUNET_MessageHeader *message) | ||
773 | { | ||
774 | GNUNET_break (0); | ||
775 | } | ||
776 | |||
718 | /* end of gnunet-service-testbed_barriers.c */ | 777 | /* end of gnunet-service-testbed_barriers.c */ |