aboutsummaryrefslogtreecommitdiff
path: root/src/testbed/gnunet-service-testbed_barriers.c
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-09-01 20:46:03 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-09-01 20:46:03 +0000
commit6c684b3367b9f21ea46b0565b6e4aac8daf85f51 (patch)
treea95c4b548e49a2e750ff0b5b14e2353050d24082 /src/testbed/gnunet-service-testbed_barriers.c
parent9839451a4a8344322d6a1578540e2eb1919427d7 (diff)
downloadgnunet-6c684b3367b9f21ea46b0565b6e4aac8daf85f51.tar.gz
gnunet-6c684b3367b9f21ea46b0565b6e4aac8daf85f51.zip
- more barrier stuff
Diffstat (limited to 'src/testbed/gnunet-service-testbed_barriers.c')
-rw-r--r--src/testbed/gnunet-service-testbed_barriers.c123
1 files changed, 121 insertions, 2 deletions
diff --git a/src/testbed/gnunet-service-testbed_barriers.c b/src/testbed/gnunet-service-testbed_barriers.c
index f82e38c96..c12075d66 100644
--- a/src/testbed/gnunet-service-testbed_barriers.c
+++ b/src/testbed/gnunet-service-testbed_barriers.c
@@ -34,6 +34,13 @@
34 34
35 35
36/** 36/**
37 * Test to see if local peers have reached the required quorum of a barrier
38 */
39#define LOCAL_QUORUM_REACHED(barrier) \
40 ((barrier->quorum * GST_num_local_peers) <= (barrier->nreached * 100))
41
42
43/**
37 * Barrier 44 * Barrier
38 */ 45 */
39struct Barrier; 46struct Barrier;
@@ -60,6 +67,7 @@ struct MessageQueue
60 struct GNUNET_MessageHeader *msg; 67 struct GNUNET_MessageHeader *msg;
61}; 68};
62 69
70
63/** 71/**
64 * Context to be associated with each client 72 * Context to be associated with each client
65 */ 73 */
@@ -103,6 +111,38 @@ struct ClientCtx
103 111
104 112
105/** 113/**
114 * Wrapper around Barrier handle
115 */
116struct WBarrier
117{
118 /**
119 * DLL next pointer
120 */
121 struct WBarrier *next;
122
123 /**
124 * DLL prev pointer
125 */
126 struct WBarrier *prev;
127
128 /**
129 * The local barrier associated with the creation of this wrapper
130 */
131 struct Barrier *barrier;
132
133 /**
134 * The barrier handle from API
135 */
136 struct GNUNET_TESTBED_Barrier *hbarrier;
137
138 /**
139 * Has this barrier been crossed?
140 */
141 uint8_t reached;
142};
143
144
145/**
106 * Barrier 146 * Barrier
107 */ 147 */
108struct Barrier 148struct Barrier
@@ -128,6 +168,26 @@ struct Barrier
128 struct ClientCtx *tail; 168 struct ClientCtx *tail;
129 169
130 /** 170 /**
171 * DLL head for the list of barrier handles
172 */
173 struct WBarrier *whead;
174
175 /**
176 * DLL tail for the list of barrier handles
177 */
178 struct WBarrier *wtail;
179
180 /**
181 * Number of barriers wrapped in the above DLL
182 */
183 unsigned int num_wbarriers;
184
185 /**
186 * Number of wrapped barriers reached so far
187 */
188 unsigned int num_wbarriers_reached;
189
190 /**
131 * Number of peers which have reached this barrier 191 * Number of peers which have reached this barrier
132 */ 192 */
133 unsigned int nreached; 193 unsigned int nreached;
@@ -364,7 +424,7 @@ handle_barrier_wait (void *cls, struct GNUNET_SERVER_Client *client,
364 client_ctx->barrier = barrier; 424 client_ctx->barrier = barrier;
365 GNUNET_CONTAINER_DLL_insert_tail (barrier->head, barrier->tail, client_ctx); 425 GNUNET_CONTAINER_DLL_insert_tail (barrier->head, barrier->tail, client_ctx);
366 barrier->nreached++; 426 barrier->nreached++;
367 if ((barrier->quorum * GST_num_local_peers) <= (barrier->nreached * 100)) 427 if (LOCAL_QUORUM_REACHED (barrier))
368 notify_task_cb (barrier, NULL); 428 notify_task_cb (barrier, NULL);
369 } 429 }
370 GNUNET_SERVER_receive_done (client, GNUNET_OK); 430 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -423,12 +483,64 @@ GST_barriers_init (struct GNUNET_CONFIGURATION_Handle *cfg)
423void 483void
424GST_barriers_stop () 484GST_barriers_stop ()
425{ 485{
486 GNUNET_assert (NULL != barrier_map);
487 GNUNET_CONTAINER_multihashmap_destroy (barrier_map);
426 GNUNET_assert (NULL != ctx); 488 GNUNET_assert (NULL != ctx);
427 GNUNET_SERVICE_stop (ctx); 489 GNUNET_SERVICE_stop (ctx);
428} 490}
429 491
430 492
431/** 493/**
494 * Functions of this type are to be given as callback argument to
495 * GNUNET_TESTBED_barrier_init(). The callback will be called when status
496 * information is available for the barrier.
497 *
498 * @param cls the closure given to GNUNET_TESTBED_barrier_init()
499 * @param name the name of the barrier
500 * @param barrier the barrier handle
501 * @param status status of the barrier; GNUNET_OK if the barrier is crossed;
502 * GNUNET_SYSERR upon error
503 * @param emsg if the status were to be GNUNET_SYSERR, this parameter has the
504 * error messsage
505 */
506static void
507wbarrier_status_cb (void *cls, const char *name,
508 struct GNUNET_TESTBED_Barrier *b_,
509 int status, const char *emsg)
510{
511 struct WBarrier *wrapper = cls;
512 struct Barrier *barrier = wrapper->barrier;
513
514 GNUNET_assert (b_ == wrapper->hbarrier);
515 wrapper->hbarrier = NULL;
516 GNUNET_CONTAINER_DLL_remove (barrier->whead, barrier->wtail, wrapper);
517 GNUNET_free (wrapper);
518 if (GNUNET_SYSERR == status)
519 {
520 LOG (GNUNET_ERROR_TYPE_ERROR,
521 "Initialising barrier (%s) failed at a sub-controller: %s\n",
522 barrier->name, (NULL != emsg) ? emsg : "NULL");
523 while (NULL != (wrapper = barrier->whead))
524 {
525 GNUNET_TESTBED_barrier_cancel (wrapper->hbarrier);
526 GNUNET_CONTAINER_DLL_remove (barrier->whead, barrier->wtail, wrapper);
527 GNUNET_free (wrapper);
528 }
529 /* Send parent controller failure message */
530 GNUNET_break (0);
531 }
532 barrier->num_wbarriers_reached++;
533 if ((barrier->num_wbarriers_reached == barrier->num_wbarriers)
534 && (LOCAL_QUORUM_REACHED (barrier)))
535 {
536 /* Send parent controller success status message */
537 GNUNET_break (0);
538 }
539 return;
540}
541
542
543/**
432 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages. This 544 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages. This
433 * message should always come from a parent controller or the testbed API if we 545 * message should always come from a parent controller or the testbed API if we
434 * are the root controller. 546 * are the root controller.
@@ -448,6 +560,7 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client,
448 const char *name; 560 const char *name;
449 struct Barrier *barrier; 561 struct Barrier *barrier;
450 struct Slave *slave; 562 struct Slave *slave;
563 struct WBarrier *wrapper;
451 struct GNUNET_HashCode hash; 564 struct GNUNET_HashCode hash;
452 size_t name_len; 565 size_t name_len;
453 uint64_t op_id; 566 uint64_t op_id;
@@ -506,6 +619,12 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client,
506 GNUNET_break (0);/* May happen when we are connecting to the controller */ 619 GNUNET_break (0);/* May happen when we are connecting to the controller */
507 continue; 620 continue;
508 } 621 }
509 GNUNET_break (0); /* FIXME */ 622 wrapper = GNUNET_malloc (sizeof (struct WBarrier));
623 wrapper->barrier = barrier;
624 wrapper->hbarrier = GNUNET_TESTBED_barrier_init (slave->controller,
625 barrier->name,
626 barrier->quorum,
627 &wbarrier_status_cb,
628 wrapper);
510 } 629 }
511} 630}