aboutsummaryrefslogtreecommitdiff
path: root/src/testbed/gnunet-service-testbed_barriers.c
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-09-02 14:25:54 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-09-02 14:25:54 +0000
commit6ea7ba4bfcd11cbfc0b828f12d881f983d277bc7 (patch)
tree1de1beff9a9c31428c01e2cb896a0e82fe1bd274 /src/testbed/gnunet-service-testbed_barriers.c
parentc9b0b7850190a2deec71bc8029a8db58ad809fd5 (diff)
downloadgnunet-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.c113
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 */
356static void 358static void
357send_barrier_status_msg (struct Barrier *barrier, 359send_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 */
390static void
391send_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 */
770void
771GST_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 */