aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-09-02 10:01:01 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-09-02 10:01:01 +0000
commit719fb81dbaf034f624abaf6cc0a51c05446191f4 (patch)
treef31237c562e3e442ad20cd9c0308bcd13db7ae2f /src
parent6c684b3367b9f21ea46b0565b6e4aac8daf85f51 (diff)
downloadgnunet-719fb81dbaf034f624abaf6cc0a51c05446191f4.tar.gz
gnunet-719fb81dbaf034f624abaf6cc0a51c05446191f4.zip
- more barrier stuff
Diffstat (limited to 'src')
-rw-r--r--src/testbed/gnunet-service-testbed_barriers.c160
-rw-r--r--src/testbed/testbed.h9
-rw-r--r--src/testbed/testbed_api.c2
-rw-r--r--src/testbed/testbed_api.h2
-rw-r--r--src/testbed/testbed_api_barriers.c12
5 files changed, 141 insertions, 44 deletions
diff --git a/src/testbed/gnunet-service-testbed_barriers.c b/src/testbed/gnunet-service-testbed_barriers.c
index c12075d66..e0d0e2f18 100644
--- a/src/testbed/gnunet-service-testbed_barriers.c
+++ b/src/testbed/gnunet-service-testbed_barriers.c
@@ -153,6 +153,11 @@ struct Barrier
153 struct GNUNET_HashCode hash; 153 struct GNUNET_HashCode hash;
154 154
155 /** 155 /**
156 * The client handle to the master controller
157 */
158 struct GNUNET_SERVER_Client *client;
159
160 /**
156 * The name of the barrier 161 * The name of the barrier
157 */ 162 */
158 char *name; 163 char *name;
@@ -178,6 +183,16 @@ struct Barrier
178 struct WBarrier *wtail; 183 struct WBarrier *wtail;
179 184
180 /** 185 /**
186 * Identifier for the timeout task
187 */
188 GNUNET_SCHEDULER_TaskIdentifier tout_task;
189
190 /**
191 * The status of this barrier
192 */
193 enum GNUNET_TESTBED_BarrierStatus status;
194
195 /**
181 * Number of barriers wrapped in the above DLL 196 * Number of barriers wrapped in the above DLL
182 */ 197 */
183 unsigned int num_wbarriers; 198 unsigned int num_wbarriers;
@@ -188,6 +203,11 @@ struct Barrier
188 unsigned int num_wbarriers_reached; 203 unsigned int num_wbarriers_reached;
189 204
190 /** 205 /**
206 * Number of wrapped barrier initialised so far
207 */
208 unsigned int num_wbarriers_inited;
209
210 /**
191 * Number of peers which have reached this barrier 211 * Number of peers which have reached this barrier
192 */ 212 */
193 unsigned int nreached; 213 unsigned int nreached;
@@ -287,7 +307,6 @@ queue_message (struct ClientCtx *ctx, struct GNUNET_MessageHeader *msg)
287} 307}
288 308
289 309
290#if 0
291/** 310/**
292 * Function to remove a barrier from the barrier map and cleanup resources 311 * Function to remove a barrier from the barrier map and cleanup resources
293 * occupied by a barrier 312 * occupied by a barrier
@@ -301,33 +320,63 @@ remove_barrier (struct Barrier *barrier)
301 &barrier->hash, 320 &barrier->hash,
302 barrier)); 321 barrier));
303 GNUNET_free (barrier->name); 322 GNUNET_free (barrier->name);
323 if (NULL != barrier->client)
324 GNUNET_SERVER_client_drop (barrier->client);
304 GNUNET_free (barrier); 325 GNUNET_free (barrier);
305} 326}
306 327
307 328
308/** 329/**
309 * Function called upon timeout while waiting for a response from the 330 * Cancels all subcontroller barrier handles
310 * subcontrollers to barrier init message
311 * 331 *
312 * @param 332 * @param barrier the local barrier
313 * @return
314 */ 333 */
315static void 334static void
316fwd_tout_barrier_init (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 335cancel_wrappers (struct Barrier *barrier)
317{ 336{
318 struct ForwardedOperationContext *foctx = cls; 337 struct WBarrier *wrapper;
319 struct Barrier *barrier = foctx->cls; 338
320 339 while (NULL != (wrapper = barrier->whead))
321 barrier->nslaves--;
322 barrier->timedout = GNUNET_YES;
323 if (0 == barrier->nslaves)
324 { 340 {
325 GST_send_operation_fail_msg (foctx->client, foctx->operation_id, 341 GNUNET_TESTBED_barrier_cancel (wrapper->hbarrier);
326 "Timeout while contacting a slave controller"); 342 GNUNET_CONTAINER_DLL_remove (barrier->whead, barrier->wtail, wrapper);
327 remove_barrier (barrier); 343 GNUNET_free (wrapper);
328 } 344 }
329} 345}
330#endif 346
347
348/**
349 * Sends a barrier failed message
350 *
351 * @param barrier the corresponding barrier
352 * @param status the status of the barrier
353 * @param emsg the error message; should be non-NULL for
354 * status=BARRIER_STATUS_ERROR
355 */
356static void
357send_barrier_status_msg (struct Barrier *barrier,
358 enum GNUNET_TESTBED_BarrierStatus status,
359 const char *emsg)
360{
361 struct GNUNET_TESTBED_BarrierStatusMsg *msg;
362 size_t name_len;
363 uint16_t msize;
364
365 GNUNET_assert ((NULL == emsg) || (BARRIER_STATUS_ERROR == status));
366 name_len = strlen (barrier->name) + 1;
367 msize = sizeof (struct GNUNET_TESTBED_BarrierStatusMsg)
368 + name_len
369 + (NULL == emsg) ? 0 : strlen (emsg) + 1;
370 msg = GNUNET_malloc (msize);
371 msg->status = htons (status);
372 msg->name_len = htons (name_len);
373 (void) memcpy (msg->data, barrier->name, name_len);
374 if (NULL != emsg)
375 (void) memcpy (msg->data + name_len, emsg, strlen (emsg) + 1);
376 GST_queue_message (barrier->client, &msg->header);
377}
378
379
331 380
332/** 381/**
333 * Task for sending barrier crossed notifications to waiting client 382 * Task for sending barrier crossed notifications to waiting client
@@ -340,13 +389,13 @@ notify_task_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
340{ 389{
341 struct Barrier *barrier = cls; 390 struct Barrier *barrier = cls;
342 struct ClientCtx *client_ctx; 391 struct ClientCtx *client_ctx;
343 struct GNUNET_TESTBED_BarrierStatus *msg; 392 struct GNUNET_TESTBED_BarrierStatusMsg *msg;
344 struct GNUNET_MessageHeader *dup_msg; 393 struct GNUNET_MessageHeader *dup_msg;
345 uint16_t name_len; 394 uint16_t name_len;
346 uint16_t msize; 395 uint16_t msize;
347 396
348 name_len = strlen (barrier->name) + 1; 397 name_len = strlen (barrier->name) + 1;
349 msize = sizeof (struct GNUNET_TESTBED_BarrierStatus) + name_len; 398 msize = sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) + name_len;
350 msg = GNUNET_malloc (msize); 399 msg = GNUNET_malloc (msize);
351 msg->header.size = htons (msize); 400 msg->header.size = htons (msize);
352 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS); 401 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS);
@@ -505,8 +554,9 @@ GST_barriers_stop ()
505 */ 554 */
506static void 555static void
507wbarrier_status_cb (void *cls, const char *name, 556wbarrier_status_cb (void *cls, const char *name,
508 struct GNUNET_TESTBED_Barrier *b_, 557 struct GNUNET_TESTBED_Barrier *b_,
509 int status, const char *emsg) 558 enum GNUNET_TESTBED_BarrierStatus status,
559 const char *emsg)
510{ 560{
511 struct WBarrier *wrapper = cls; 561 struct WBarrier *wrapper = cls;
512 struct Barrier *barrier = wrapper->barrier; 562 struct Barrier *barrier = wrapper->barrier;
@@ -515,32 +565,59 @@ wbarrier_status_cb (void *cls, const char *name,
515 wrapper->hbarrier = NULL; 565 wrapper->hbarrier = NULL;
516 GNUNET_CONTAINER_DLL_remove (barrier->whead, barrier->wtail, wrapper); 566 GNUNET_CONTAINER_DLL_remove (barrier->whead, barrier->wtail, wrapper);
517 GNUNET_free (wrapper); 567 GNUNET_free (wrapper);
518 if (GNUNET_SYSERR == status) 568 if (BARRIER_STATUS_ERROR == status)
519 { 569 {
520 LOG (GNUNET_ERROR_TYPE_ERROR, 570 LOG (GNUNET_ERROR_TYPE_ERROR,
521 "Initialising barrier (%s) failed at a sub-controller: %s\n", 571 "Initialising barrier `%s' failed at a sub-controller: %s\n",
522 barrier->name, (NULL != emsg) ? emsg : "NULL"); 572 barrier->name, (NULL != emsg) ? emsg : "NULL");
523 while (NULL != (wrapper = barrier->whead)) 573 cancel_wrappers (barrier);
524 { 574 if (NULL == emsg)
525 GNUNET_TESTBED_barrier_cancel (wrapper->hbarrier); 575 emsg = "Initialisation failed at a sub-controller";
526 GNUNET_CONTAINER_DLL_remove (barrier->whead, barrier->wtail, wrapper); 576 send_barrier_status_msg (barrier, BARRIER_STATUS_ERROR, emsg);
527 GNUNET_free (wrapper); 577 return;
528 }
529 /* Send parent controller failure message */
530 GNUNET_break (0);
531 } 578 }
532 barrier->num_wbarriers_reached++; 579 switch (status)
533 if ((barrier->num_wbarriers_reached == barrier->num_wbarriers)
534 && (LOCAL_QUORUM_REACHED (barrier)))
535 { 580 {
536 /* Send parent controller success status message */ 581 case BARRIER_STATUS_CROSSED:
537 GNUNET_break (0); 582 barrier->num_wbarriers_reached++;
583 if ((barrier->num_wbarriers_reached == barrier->num_wbarriers)
584 && (LOCAL_QUORUM_REACHED (barrier)))
585 send_barrier_status_msg (barrier, BARRIER_STATUS_CROSSED, NULL);
586 break;
587 case BARRIER_STATUS_INITIALISED:
588 barrier->num_wbarriers_inited++;
589 if (barrier->num_wbarriers_inited == barrier->num_wbarriers)
590 send_barrier_status_msg (barrier, BARRIER_STATUS_INITIALISED, NULL);
591 break;
592 case BARRIER_STATUS_ERROR:
593 GNUNET_assert (0);
538 } 594 }
539 return; 595 return;
540} 596}
541 597
542 598
543/** 599/**
600 * Function called upon timeout while waiting for a response from the
601 * subcontrollers to barrier init message
602 *
603 * @param
604 * @return
605 */
606static void
607fwd_tout_barrier_init (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
608{
609 struct Barrier *barrier = cls;
610
611 barrier->nslaves--;
612 barrier->timedout = GNUNET_YES;
613 cancel_wrappers (barrier);
614 send_barrier_status_msg (barrier, BARRIER_STATUS_ERROR,
615 "Timedout while propagating barrier initialisation\n");
616 remove_barrier (barrier);
617}
618
619
620/**
544 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages. This 621 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages. This
545 * message should always come from a parent controller or the testbed API if we 622 * message should always come from a parent controller or the testbed API if we
546 * are the root controller. 623 * are the root controller.
@@ -603,6 +680,8 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client,
603 barrier->name = GNUNET_malloc (name_len + 1); 680 barrier->name = GNUNET_malloc (name_len + 1);
604 barrier->name[name_len] = '\0'; 681 barrier->name[name_len] = '\0';
605 (void) memcpy (barrier->name, name, name_len); 682 (void) memcpy (barrier->name, name, name_len);
683 barrier->client = client;
684 GNUNET_SERVER_client_keep (client);
606 GNUNET_assert (GNUNET_OK == 685 GNUNET_assert (GNUNET_OK ==
607 GNUNET_CONTAINER_multihashmap_put (barrier_map, 686 GNUNET_CONTAINER_multihashmap_put (barrier_map,
608 &barrier->hash, 687 &barrier->hash,
@@ -621,10 +700,19 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client,
621 } 700 }
622 wrapper = GNUNET_malloc (sizeof (struct WBarrier)); 701 wrapper = GNUNET_malloc (sizeof (struct WBarrier));
623 wrapper->barrier = barrier; 702 wrapper->barrier = barrier;
703 GNUNET_CONTAINER_DLL_insert_tail (barrier->whead, barrier->wtail, wrapper);
624 wrapper->hbarrier = GNUNET_TESTBED_barrier_init (slave->controller, 704 wrapper->hbarrier = GNUNET_TESTBED_barrier_init (slave->controller,
625 barrier->name, 705 barrier->name,
626 barrier->quorum, 706 barrier->quorum,
627 &wbarrier_status_cb, 707 &wbarrier_status_cb,
628 wrapper); 708 wrapper);
629 } 709 }
710 if (NULL == barrier->whead) /* No further propagation */
711 send_barrier_status_msg (barrier, BARRIER_STATUS_INITIALISED, NULL);
712 else
713 barrier->tout_task = GNUNET_SCHEDULER_add_delayed (MESSAGE_SEND_TIMEOUT (30),
714 &fwd_tout_barrier_init,
715 barrier);
630} 716}
717
718/* end of gnunet-service-testbed_barriers.c */
diff --git a/src/testbed/testbed.h b/src/testbed/testbed.h
index 3b159591d..73cf8c294 100644
--- a/src/testbed/testbed.h
+++ b/src/testbed/testbed.h
@@ -768,6 +768,11 @@ struct GNUNET_TESTBED_ManagePeerServiceMessage
768}; 768};
769 769
770 770
771/**************************************/
772/* Barriers IPC messages and protocol */
773/**************************************/
774
775
771/** 776/**
772 * Message to initialise a barrier 777 * Message to initialise a barrier
773 */ 778 */
@@ -803,7 +808,7 @@ struct GNUNET_TESTBED_BarrierInit
803/** 808/**
804 * Message for signalling status changes of a barrier 809 * Message for signalling status changes of a barrier
805 */ 810 */
806struct GNUNET_TESTBED_BarrierStatus 811struct GNUNET_TESTBED_BarrierStatusMsg
807{ 812{
808 /** 813 /**
809 * Type is GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS 814 * Type is GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS
@@ -811,7 +816,7 @@ struct GNUNET_TESTBED_BarrierStatus
811 struct GNUNET_MessageHeader header; 816 struct GNUNET_MessageHeader header;
812 817
813 /** 818 /**
814 * status. 0 to signal success (barrier is crossed). 1 for error. 819 * status. Use enumerated values of enum BarrierStatus
815 */ 820 */
816 uint16_t status; 821 uint16_t status;
817 822
diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c
index 0a109aa7f..d5486b1c3 100644
--- a/src/testbed/testbed_api.c
+++ b/src/testbed/testbed_api.c
@@ -1163,7 +1163,7 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
1163 status = 1163 status =
1164 GNUNET_TESTBED_handle_barrier_status_ (c, 1164 GNUNET_TESTBED_handle_barrier_status_ (c,
1165 (const struct 1165 (const struct
1166 GNUNET_TESTBED_BarrierStatus *) 1166 GNUNET_TESTBED_BarrierStatusMsg *)
1167 msg); 1167 msg);
1168 break; 1168 break;
1169 default: 1169 default:
diff --git a/src/testbed/testbed_api.h b/src/testbed/testbed_api.h
index f658c08dd..39a2f711a 100644
--- a/src/testbed/testbed_api.h
+++ b/src/testbed/testbed_api.h
@@ -508,7 +508,7 @@ GNUNET_TESTBED_controller_link_ (void *op_cls,
508 */ 508 */
509int 509int
510GNUNET_TESTBED_handle_barrier_status_ (struct GNUNET_TESTBED_Controller *c, 510GNUNET_TESTBED_handle_barrier_status_ (struct GNUNET_TESTBED_Controller *c,
511 const struct GNUNET_TESTBED_BarrierStatus 511 const struct GNUNET_TESTBED_BarrierStatusMsg
512 *msg); 512 *msg);
513 513
514 514
diff --git a/src/testbed/testbed_api_barriers.c b/src/testbed/testbed_api_barriers.c
index 231e00600..ab468a088 100644
--- a/src/testbed/testbed_api_barriers.c
+++ b/src/testbed/testbed_api_barriers.c
@@ -102,7 +102,7 @@ barrier_remove (struct GNUNET_TESTBED_Barrier *barrier)
102 */ 102 */
103int 103int
104GNUNET_TESTBED_handle_barrier_status_ (struct GNUNET_TESTBED_Controller *c, 104GNUNET_TESTBED_handle_barrier_status_ (struct GNUNET_TESTBED_Controller *c,
105 const struct GNUNET_TESTBED_BarrierStatus 105 const struct GNUNET_TESTBED_BarrierStatusMsg
106 *msg) 106 *msg)
107{ 107{
108 struct GNUNET_TESTBED_Barrier *barrier; 108 struct GNUNET_TESTBED_Barrier *barrier;
@@ -119,17 +119,17 @@ GNUNET_TESTBED_handle_barrier_status_ (struct GNUNET_TESTBED_Controller *c,
119 msize = ntohs (msg->header.size); 119 msize = ntohs (msg->header.size);
120 name = msg->data; 120 name = msg->data;
121 name_len = ntohs (msg->name_len); 121 name_len = ntohs (msg->name_len);
122 if ( (sizeof (struct GNUNET_TESTBED_BarrierStatus) + name_len + 1 > msize) 122 if ( (sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) + name_len + 1 > msize)
123 || ('\0' != name[name_len]) ) 123 || ('\0' != name[name_len]) )
124 { 124 {
125 GNUNET_break_op (0); 125 GNUNET_break_op (0);
126 return GNUNET_SYSERR; 126 return GNUNET_SYSERR;
127 } 127 }
128 status = ntohs (msg->status); 128 status = ntohs (msg->status);
129 if (0 != status) 129 if (BARRIER_STATUS_ERROR == status)
130 { 130 {
131 status = -1; 131 status = -1;
132 emsg_len = msize - (sizeof (struct GNUNET_TESTBED_BarrierStatus) + name_len 132 emsg_len = msize - (sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) + name_len
133 + 1); 133 + 1);
134 if (0 == emsg_len) 134 if (0 == emsg_len)
135 { 135 {
@@ -150,6 +150,8 @@ GNUNET_TESTBED_handle_barrier_status_ (struct GNUNET_TESTBED_Controller *c,
150 goto cleanup; 150 goto cleanup;
151 GNUNET_assert (NULL != barrier->cb); 151 GNUNET_assert (NULL != barrier->cb);
152 barrier->cb (barrier->cls, name, barrier, status, emsg); 152 barrier->cb (barrier->cls, name, barrier, status, emsg);
153 if (BARRIER_STATUS_INITIALISED == status)
154 return GNUNET_OK; /* just initialised; skip cleanup */
153 155
154 cleanup: 156 cleanup:
155 GNUNET_free_non_null (emsg); 157 GNUNET_free_non_null (emsg);
@@ -219,3 +221,5 @@ GNUNET_TESTBED_barrier_cancel (struct GNUNET_TESTBED_Barrier *barrier)
219{ 221{
220 barrier_remove (barrier); 222 barrier_remove (barrier);
221} 223}
224
225/* end of testbed_api_barriers.c */