diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2013-09-01 20:46:03 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2013-09-01 20:46:03 +0000 |
commit | 6c684b3367b9f21ea46b0565b6e4aac8daf85f51 (patch) | |
tree | a95c4b548e49a2e750ff0b5b14e2353050d24082 /src/testbed/gnunet-service-testbed_barriers.c | |
parent | 9839451a4a8344322d6a1578540e2eb1919427d7 (diff) | |
download | gnunet-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.c | 123 |
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 | */ |
39 | struct Barrier; | 46 | struct 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 | */ | ||
116 | struct 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 | */ |
108 | struct Barrier | 148 | struct 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) | |||
423 | void | 483 | void |
424 | GST_barriers_stop () | 484 | GST_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 | */ | ||
506 | static void | ||
507 | wbarrier_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 | } |