diff options
-rw-r--r-- | src/testbed/testbed_api.c | 3 | ||||
-rw-r--r-- | src/testbed/testbed_api.h | 74 | ||||
-rw-r--r-- | src/testbed/testbed_api_testbed.c | 182 |
3 files changed, 95 insertions, 164 deletions
diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c index d5486b1c3..e328456de 100644 --- a/src/testbed/testbed_api.c +++ b/src/testbed/testbed_api.c | |||
@@ -352,6 +352,9 @@ GNUNET_TESTBED_remove_opc_ (const struct GNUNET_TESTBED_Controller *c, | |||
352 | GNUNET_CONTAINER_multihashmap32_remove (c->opc_map, | 352 | GNUNET_CONTAINER_multihashmap32_remove (c->opc_map, |
353 | (uint32_t) opc->id, | 353 | (uint32_t) opc->id, |
354 | opc)); | 354 | opc)); |
355 | if ( (0 == GNUNET_CONTAINER_multihashmap32_size (c->opc_map)) | ||
356 | && (NULL != c->opcq_empty_cb) ) | ||
357 | c->opcq_empty_cb (c->opcq_empty_cls); | ||
355 | } | 358 | } |
356 | 359 | ||
357 | 360 | ||
diff --git a/src/testbed/testbed_api.h b/src/testbed/testbed_api.h index 39a2f711a..f09bb61b9 100644 --- a/src/testbed/testbed_api.h +++ b/src/testbed/testbed_api.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #ifndef TESTBED_API_H | 27 | #ifndef TESTBED_API_H |
28 | #define TESTBED_API_H | 28 | #define TESTBED_API_H |
29 | 29 | ||
30 | #include "gnunet_scheduler_lib.h" | ||
30 | #include "gnunet_testbed_service.h" | 31 | #include "gnunet_testbed_service.h" |
31 | #include "testbed.h" | 32 | #include "testbed.h" |
32 | #include "testbed_helper.h" | 33 | #include "testbed_helper.h" |
@@ -178,6 +179,14 @@ struct OperationContext | |||
178 | 179 | ||
179 | 180 | ||
180 | /** | 181 | /** |
182 | * Operation empty callback | ||
183 | * | ||
184 | * @param cls closure | ||
185 | */ | ||
186 | typedef void (*TESTBED_opcq_empty_cb) (void *cls); | ||
187 | |||
188 | |||
189 | /** | ||
181 | * Handle to interact with a GNUnet testbed controller. Each | 190 | * Handle to interact with a GNUnet testbed controller. Each |
182 | * controller has at least one master handle which is created when the | 191 | * controller has at least one master handle which is created when the |
183 | * controller is created; this master handle interacts with the | 192 | * controller is created; this master handle interacts with the |
@@ -240,6 +249,16 @@ struct GNUNET_TESTBED_Controller | |||
240 | struct GNUNET_CONTAINER_MultiHashMap32 *opc_map; | 249 | struct GNUNET_CONTAINER_MultiHashMap32 *opc_map; |
241 | 250 | ||
242 | /** | 251 | /** |
252 | * If this callback is not NULL, schedule it as a task when opc_map gets empty | ||
253 | */ | ||
254 | TESTBED_opcq_empty_cb opcq_empty_cb; | ||
255 | |||
256 | /** | ||
257 | * Closure for the above task | ||
258 | */ | ||
259 | void *opcq_empty_cls; | ||
260 | |||
261 | /** | ||
243 | * Operation queue for simultaneous operations | 262 | * Operation queue for simultaneous operations |
244 | */ | 263 | */ |
245 | struct OperationQueue *opq_parallel_operations; | 264 | struct OperationQueue *opq_parallel_operations; |
@@ -442,61 +461,6 @@ GNUNET_TESTBED_get_slave_config_ (void *op_cls, | |||
442 | 461 | ||
443 | 462 | ||
444 | /** | 463 | /** |
445 | * Same as the GNUNET_TESTBED_controller_link_2, but with ids for delegated host | ||
446 | * and slave host | ||
447 | * | ||
448 | * @param op_cls the operation closure for the event which is generated to | ||
449 | * signal success or failure of this operation | ||
450 | * @param master handle to the master controller who creates the association | ||
451 | * @param delegated_host_id id of the host to which requests should be delegated | ||
452 | * @param slave_host_id id of the host which is used to run the slave controller | ||
453 | * @param sxcfg serialized and compressed configuration | ||
454 | * @param sxcfg_size the size sxcfg | ||
455 | * @param scfg_size the size of uncompressed serialized configuration | ||
456 | * @param is_subordinate GNUNET_YES if the controller at delegated_host should | ||
457 | * be started by the slave controller; GNUNET_NO if the slave | ||
458 | * controller has to connect to the already started delegated | ||
459 | * controller via TCP/IP | ||
460 | * @return the operation handle | ||
461 | */ | ||
462 | struct GNUNET_TESTBED_Operation * | ||
463 | GNUNET_TESTBED_controller_link_2_ (void *op_cls, | ||
464 | struct GNUNET_TESTBED_Controller *master, | ||
465 | uint32_t delegated_host_id, | ||
466 | uint32_t slave_host_id, const char *sxcfg, | ||
467 | size_t sxcfg_size, size_t scfg_size, | ||
468 | int is_subordinate); | ||
469 | |||
470 | |||
471 | /** | ||
472 | * Same as the GNUNET_TESTBED_controller_link, but with ids for delegated host | ||
473 | * and slave host | ||
474 | * | ||
475 | * @param op_cls the operation closure for the event which is generated to | ||
476 | * signal success or failure of this operation | ||
477 | * @param master handle to the master controller who creates the association | ||
478 | * @param delegated_host_id id of the host to which requests should be | ||
479 | * delegated; cannot be NULL | ||
480 | * @param slave_host_id id of the host which should connect to controller | ||
481 | * running on delegated host ; use NULL to make the master controller | ||
482 | * connect to the delegated host | ||
483 | * @param slave_cfg configuration to use for the slave controller | ||
484 | * @param is_subordinate GNUNET_YES if the controller at delegated_host should | ||
485 | * be started by the slave controller; GNUNET_NO if the slave | ||
486 | * controller has to connect to the already started delegated | ||
487 | * controller via TCP/IP | ||
488 | * @return the operation handle | ||
489 | */ | ||
490 | struct GNUNET_TESTBED_Operation * | ||
491 | GNUNET_TESTBED_controller_link_ (void *op_cls, | ||
492 | struct GNUNET_TESTBED_Controller *master, | ||
493 | uint32_t delegated_host_id, | ||
494 | uint32_t slave_host_id, | ||
495 | const struct GNUNET_CONFIGURATION_Handle | ||
496 | *slave_cfg, int is_subordinate); | ||
497 | |||
498 | |||
499 | /** | ||
500 | * Handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages. This | 464 | * Handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages. This |
501 | * function is defined in @file testbed_api_barriers.c | 465 | * function is defined in @file testbed_api_barriers.c |
502 | * | 466 | * |
diff --git a/src/testbed/testbed_api_testbed.c b/src/testbed/testbed_api_testbed.c index 064e43b9f..dae364699 100644 --- a/src/testbed/testbed_api_testbed.c +++ b/src/testbed/testbed_api_testbed.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "platform.h" | 28 | #include "platform.h" |
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | #include "gnunet_testbed_service.h" | 30 | #include "gnunet_testbed_service.h" |
31 | #include "testbed_api.h" | ||
31 | #include "testbed_api_peers.h" | 32 | #include "testbed_api_peers.h" |
32 | #include "testbed_api_hosts.h" | 33 | #include "testbed_api_hosts.h" |
33 | #include "testbed_api_topology.h" | 34 | #include "testbed_api_topology.h" |
@@ -242,11 +243,6 @@ struct RunContext | |||
242 | GNUNET_SCHEDULER_TaskIdentifier register_hosts_task; | 243 | GNUNET_SCHEDULER_TaskIdentifier register_hosts_task; |
243 | 244 | ||
244 | /** | 245 | /** |
245 | * Task to be run while shutting down | ||
246 | */ | ||
247 | GNUNET_SCHEDULER_TaskIdentifier shutdown_run_task; | ||
248 | |||
249 | /** | ||
250 | * Task to be run of a timeout | 246 | * Task to be run of a timeout |
251 | */ | 247 | */ |
252 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | 248 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; |
@@ -257,11 +253,6 @@ struct RunContext | |||
257 | GNUNET_SCHEDULER_TaskIdentifier interrupt_task; | 253 | GNUNET_SCHEDULER_TaskIdentifier interrupt_task; |
258 | 254 | ||
259 | /** | 255 | /** |
260 | * Task for cleaning up the run context and various resources it uses | ||
261 | */ | ||
262 | GNUNET_SCHEDULER_TaskIdentifier cleanup_task; | ||
263 | |||
264 | /** | ||
265 | * The event mask for the controller | 256 | * The event mask for the controller |
266 | */ | 257 | */ |
267 | uint64_t event_mask; | 258 | uint64_t event_mask; |
@@ -448,7 +439,7 @@ remove_rcop (struct RunContext *rc, struct RunContextOperation *rcop) | |||
448 | * @param tc the task context from scheduler | 439 | * @param tc the task context from scheduler |
449 | */ | 440 | */ |
450 | static void | 441 | static void |
451 | cleanup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 442 | cleanup (void *cls) |
452 | { | 443 | { |
453 | struct RunContext *rc = cls; | 444 | struct RunContext *rc = cls; |
454 | unsigned int hid; | 445 | unsigned int hid; |
@@ -478,20 +469,6 @@ cleanup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
478 | 469 | ||
479 | 470 | ||
480 | /** | 471 | /** |
481 | * Perform the cleanup task now | ||
482 | * | ||
483 | * @param rc the run context to be cleaned up | ||
484 | */ | ||
485 | static void | ||
486 | cleanup_now (struct RunContext *rc) | ||
487 | { | ||
488 | if (GNUNET_SCHEDULER_NO_TASK != rc->cleanup_task) | ||
489 | GNUNET_SCHEDULER_cancel (rc->cleanup_task); | ||
490 | rc->cleanup_task = GNUNET_SCHEDULER_add_now (&cleanup, rc); | ||
491 | } | ||
492 | |||
493 | |||
494 | /** | ||
495 | * Iterator for cleaning up elements from rcop_map | 472 | * Iterator for cleaning up elements from rcop_map |
496 | * | 473 | * |
497 | * @param cls the RunContext | 474 | * @param cls the RunContext |
@@ -514,21 +491,6 @@ rcop_cleanup_iterator (void *cls, uint32_t key, void *value) | |||
514 | 491 | ||
515 | 492 | ||
516 | /** | 493 | /** |
517 | * Cleanup existing operation in given run context | ||
518 | * | ||
519 | * @param rc the run context | ||
520 | */ | ||
521 | static void | ||
522 | cleanup_operations (struct RunContext *rc) | ||
523 | { | ||
524 | GNUNET_assert (GNUNET_SYSERR != | ||
525 | GNUNET_CONTAINER_multihashmap32_iterate (rc->rcop_map, | ||
526 | &rcop_cleanup_iterator, | ||
527 | rc)); | ||
528 | } | ||
529 | |||
530 | |||
531 | /** | ||
532 | * Cancels operations and tasks which are assigned to the given run context | 494 | * Cancels operations and tasks which are assigned to the given run context |
533 | * | 495 | * |
534 | * @param rc the RunContext | 496 | * @param rc the RunContext |
@@ -561,11 +523,6 @@ rc_cleanup_operations (struct RunContext *rc) | |||
561 | GNUNET_SCHEDULER_cancel (rc->timeout_task); | 523 | GNUNET_SCHEDULER_cancel (rc->timeout_task); |
562 | rc->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 524 | rc->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
563 | } | 525 | } |
564 | if (GNUNET_SCHEDULER_NO_TASK != rc->interrupt_task) | ||
565 | { | ||
566 | GNUNET_SCHEDULER_cancel (rc->interrupt_task); | ||
567 | rc->interrupt_task = GNUNET_SCHEDULER_NO_TASK; | ||
568 | } | ||
569 | if (NULL != rc->reg_handle) | 526 | if (NULL != rc->reg_handle) |
570 | { | 527 | { |
571 | GNUNET_TESTBED_cancel_registration (rc->reg_handle); | 528 | GNUNET_TESTBED_cancel_registration (rc->reg_handle); |
@@ -577,66 +534,71 @@ rc_cleanup_operations (struct RunContext *rc) | |||
577 | rc->topology_operation = NULL; | 534 | rc->topology_operation = NULL; |
578 | } | 535 | } |
579 | /* cancel any exiting operations */ | 536 | /* cancel any exiting operations */ |
580 | cleanup_operations (rc); | 537 | GNUNET_assert (GNUNET_SYSERR != |
538 | GNUNET_CONTAINER_multihashmap32_iterate (rc->rcop_map, | ||
539 | &rcop_cleanup_iterator, | ||
540 | rc)); | ||
581 | } | 541 | } |
582 | 542 | ||
583 | 543 | ||
584 | /** | 544 | /** |
585 | * Stops the testbed run and releases any used resources | 545 | * Cancels the scheduled interrupt task |
586 | * | 546 | * |
587 | * @param cls the tesbed run handle | 547 | * @param rc the run context |
588 | * @param tc the task context from scheduler | ||
589 | */ | 548 | */ |
590 | static void | 549 | static void |
591 | shutdown_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 550 | cancel_interrupt_task (struct RunContext *rc) |
551 | { | ||
552 | GNUNET_SCHEDULER_cancel (rc->interrupt_task); | ||
553 | rc->interrupt_task = GNUNET_SCHEDULER_NO_TASK; | ||
554 | } | ||
555 | |||
556 | |||
557 | /** | ||
558 | * This callback will be called when all the operations are completed | ||
559 | * (done/cancelled) | ||
560 | * | ||
561 | * @param cls run context | ||
562 | * @param tc scheduler task context | ||
563 | */ | ||
564 | static void | ||
565 | wait_op_completion (void *cls) | ||
592 | { | 566 | { |
593 | struct RunContext *rc = cls; | 567 | struct RunContext *rc = cls; |
594 | struct RunContextOperation *rcop; | 568 | struct RunContextOperation *rcop; |
595 | 569 | ||
596 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != rc->shutdown_run_task); | 570 | if ( (NULL == rc->cproc) |
597 | rc->shutdown_run_task = GNUNET_SCHEDULER_NO_TASK; | 571 | || (NULL == rc->c) |
598 | GNUNET_assert (GNUNET_NO == rc->shutdown); | 572 | || (GNUNET_YES == rc->shutdown) ) |
599 | rc->shutdown = GNUNET_YES; | ||
600 | rc_cleanup_operations (rc); | ||
601 | if (NULL != rc->c) | ||
602 | { | 573 | { |
603 | if (NULL != rc->peers) | 574 | if (NULL != rc->peers) |
604 | { | 575 | { |
605 | rcop = GNUNET_malloc (sizeof (struct RunContextOperation)); | 576 | GNUNET_free (rc->peers); |
606 | rcop->rc = rc; | 577 | rc->peers = NULL; |
607 | rcop->op = GNUNET_TESTBED_shutdown_peers (rc->c, rcop, NULL, NULL); | ||
608 | GNUNET_assert (NULL != rcop->op); | ||
609 | DEBUG ("Shutting down peers\n"); | ||
610 | rc->pstart_time = GNUNET_TIME_absolute_get (); | ||
611 | insert_rcop (rc, rcop); | ||
612 | return; | ||
613 | } | 578 | } |
579 | goto cleanup_; | ||
614 | } | 580 | } |
615 | rc->state = RC_PEERS_SHUTDOWN; /* No peers are present so we consider the | 581 | if (NULL == rc->peers) |
616 | * state where all peers are SHUTDOWN */ | 582 | goto cleanup_; |
617 | cleanup_now (rc); | 583 | rc->shutdown = GNUNET_YES; |
618 | } | 584 | rcop = GNUNET_malloc (sizeof (struct RunContextOperation)); |
619 | 585 | rcop->rc = rc; | |
586 | rcop->op = GNUNET_TESTBED_shutdown_peers (rc->c, rcop, NULL, NULL); | ||
587 | GNUNET_assert (NULL != rcop->op); | ||
588 | DEBUG ("Shutting down peers\n"); | ||
589 | rc->pstart_time = GNUNET_TIME_absolute_get (); | ||
590 | insert_rcop (rc, rcop); | ||
591 | return; | ||
620 | 592 | ||
621 | /** | 593 | cleanup_: |
622 | * Function to shutdown now | 594 | rc->state = RC_PEERS_SHUTDOWN; |
623 | * | 595 | cancel_interrupt_task (rc); |
624 | * @param rc the RunContext | 596 | cleanup (rc); |
625 | */ | ||
626 | static void | ||
627 | shutdown_now (struct RunContext *rc) | ||
628 | { | ||
629 | if (GNUNET_YES == rc->shutdown) | ||
630 | return; | ||
631 | if (GNUNET_SCHEDULER_NO_TASK != rc->shutdown_run_task) | ||
632 | GNUNET_SCHEDULER_cancel (rc->shutdown_run_task); | ||
633 | GNUNET_SCHEDULER_shutdown (); /* Trigger shutdown in programs using this API */ | ||
634 | rc->shutdown_run_task = GNUNET_SCHEDULER_add_now (&shutdown_run, rc); | ||
635 | } | 597 | } |
636 | 598 | ||
637 | 599 | ||
638 | /** | 600 | /** |
639 | * Task run upon any interrupt. Common ones are SIGINT & SIGTERM. | 601 | * Task run upon interrupts (SIGINT, SIGTERM) and upon scheduler shutdown. |
640 | * | 602 | * |
641 | * @param cls the RunContext which has to be acted upon | 603 | * @param cls the RunContext which has to be acted upon |
642 | * @param tc the scheduler task context | 604 | * @param tc the scheduler task context |
@@ -645,9 +607,24 @@ static void | |||
645 | interrupt (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 607 | interrupt (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
646 | { | 608 | { |
647 | struct RunContext *rc = cls; | 609 | struct RunContext *rc = cls; |
610 | struct GNUNET_TESTBED_Controller *c = rc->c; | ||
611 | unsigned int size; | ||
648 | 612 | ||
649 | rc->interrupt_task = GNUNET_SCHEDULER_NO_TASK; | 613 | /* reschedule */ |
650 | shutdown_now (rc); | 614 | rc->interrupt_task = GNUNET_SCHEDULER_add_delayed |
615 | (GNUNET_TIME_UNIT_FOREVER_REL, &interrupt, rc); | ||
616 | rc_cleanup_operations (rc); | ||
617 | if ( (GNUNET_NO == rc->shutdown) | ||
618 | && (NULL != c) | ||
619 | && (0 != (size = GNUNET_CONTAINER_multihashmap32_size (c->opc_map)))) | ||
620 | { | ||
621 | LOG (GNUNET_ERROR_TYPE_WARNING, "Shutdown postponed as there are " | ||
622 | "%u operations currently active\n", size); | ||
623 | c->opcq_empty_cb = &wait_op_completion; | ||
624 | c->opcq_empty_cls = rc; | ||
625 | return; | ||
626 | } | ||
627 | wait_op_completion (rc); | ||
651 | } | 628 | } |
652 | 629 | ||
653 | 630 | ||
@@ -721,7 +698,7 @@ peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg) | |||
721 | if (NULL != emsg) | 698 | if (NULL != emsg) |
722 | LOG (GNUNET_ERROR_TYPE_ERROR, "Error while creating a peer: %s\n", | 699 | LOG (GNUNET_ERROR_TYPE_ERROR, "Error while creating a peer: %s\n", |
723 | emsg); | 700 | emsg); |
724 | shutdown_now (rc); | 701 | GNUNET_SCHEDULER_shutdown (); |
725 | return; | 702 | return; |
726 | } | 703 | } |
727 | rc->peers[rc->peer_count] = peer; | 704 | rc->peers[rc->peer_count] = peer; |
@@ -830,7 +807,7 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event) | |||
830 | if (NULL != event->details.operation_finished.emsg) | 807 | if (NULL != event->details.operation_finished.emsg) |
831 | { | 808 | { |
832 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Linking controllers failed. Exiting")); | 809 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Linking controllers failed. Exiting")); |
833 | shutdown_now (rc); | 810 | GNUNET_SCHEDULER_shutdown (); |
834 | } | 811 | } |
835 | else | 812 | else |
836 | rc->reg_hosts++; | 813 | rc->reg_hosts++; |
@@ -846,7 +823,7 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event) | |||
846 | return; | 823 | return; |
847 | default: | 824 | default: |
848 | GNUNET_break (0); | 825 | GNUNET_break (0); |
849 | shutdown_now (rc); | 826 | GNUNET_SCHEDULER_shutdown (); |
850 | return; | 827 | return; |
851 | } | 828 | } |
852 | } | 829 | } |
@@ -862,7 +839,7 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event) | |||
862 | { | 839 | { |
863 | LOG (GNUNET_ERROR_TYPE_ERROR, "A operation has failed with error: %s\n", | 840 | LOG (GNUNET_ERROR_TYPE_ERROR, "A operation has failed with error: %s\n", |
864 | event->details.operation_finished.emsg); | 841 | event->details.operation_finished.emsg); |
865 | shutdown_now (rc); | 842 | GNUNET_SCHEDULER_shutdown (); |
866 | return; | 843 | return; |
867 | } | 844 | } |
868 | GNUNET_assert (GNUNET_YES == rc->shutdown); | 845 | GNUNET_assert (GNUNET_YES == rc->shutdown); |
@@ -875,7 +852,7 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event) | |||
875 | GNUNET_free_non_null (rc->peers); | 852 | GNUNET_free_non_null (rc->peers); |
876 | rc->peers = NULL; | 853 | rc->peers = NULL; |
877 | DEBUG ("Peers shut down in %s\n", prof_time (rc)); | 854 | DEBUG ("Peers shut down in %s\n", prof_time (rc)); |
878 | cleanup_now (rc); | 855 | GNUNET_SCHEDULER_shutdown (); |
879 | break; | 856 | break; |
880 | default: | 857 | default: |
881 | GNUNET_assert (0); | 858 | GNUNET_assert (0); |
@@ -972,7 +949,7 @@ host_registration_completion (void *cls, const char *emsg) | |||
972 | { | 949 | { |
973 | LOG (GNUNET_ERROR_TYPE_WARNING, | 950 | LOG (GNUNET_ERROR_TYPE_WARNING, |
974 | _("Host registration failed for a host. Error: %s\n"), emsg); | 951 | _("Host registration failed for a host. Error: %s\n"), emsg); |
975 | shutdown_now (rc); | 952 | GNUNET_SCHEDULER_shutdown (); |
976 | return; | 953 | return; |
977 | } | 954 | } |
978 | rc->register_hosts_task = GNUNET_SCHEDULER_add_now (®ister_hosts, rc); | 955 | rc->register_hosts_task = GNUNET_SCHEDULER_add_now (®ister_hosts, rc); |
@@ -1037,20 +1014,7 @@ controller_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1037 | { | 1014 | { |
1038 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1015 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1039 | _("Controller crash detected. Shutting down.\n")); | 1016 | _("Controller crash detected. Shutting down.\n")); |
1040 | rc->cproc = NULL; | 1017 | GNUNET_SCHEDULER_shutdown (); |
1041 | rc_cleanup_operations (rc); | ||
1042 | if (NULL != rc->peers) | ||
1043 | { | ||
1044 | GNUNET_free (rc->peers); | ||
1045 | rc->peers = NULL; | ||
1046 | } | ||
1047 | if (GNUNET_YES == rc->shutdown) | ||
1048 | { | ||
1049 | rc->state = RC_PEERS_SHUTDOWN; | ||
1050 | cleanup_now (rc); | ||
1051 | } | ||
1052 | else | ||
1053 | shutdown_now (rc); | ||
1054 | return; | 1018 | return; |
1055 | } | 1019 | } |
1056 | GNUNET_CONFIGURATION_destroy (rc->cfg); | 1020 | GNUNET_CONFIGURATION_destroy (rc->cfg); |
@@ -1143,7 +1107,7 @@ host_habitable_cb (void *cls, const struct GNUNET_TESTBED_Host *host, | |||
1143 | else | 1107 | else |
1144 | LOG (GNUNET_ERROR_TYPE_ERROR, | 1108 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1145 | _("Testbed cannot be started on localhost\n")); | 1109 | _("Testbed cannot be started on localhost\n")); |
1146 | shutdown_now (rc); | 1110 | GNUNET_SCHEDULER_shutdown (); |
1147 | return; | 1111 | return; |
1148 | } | 1112 | } |
1149 | rc->reg_hosts++; | 1113 | rc->reg_hosts++; |
@@ -1181,7 +1145,7 @@ host_habitable_cb (void *cls, const struct GNUNET_TESTBED_Host *host, | |||
1181 | if (NULL == rc->cproc) | 1145 | if (NULL == rc->cproc) |
1182 | { | 1146 | { |
1183 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Cannot start the master controller")); | 1147 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Cannot start the master controller")); |
1184 | shutdown_now (rc); | 1148 | GNUNET_SCHEDULER_shutdown (); |
1185 | } | 1149 | } |
1186 | } | 1150 | } |
1187 | 1151 | ||
@@ -1199,7 +1163,7 @@ timeout_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1199 | 1163 | ||
1200 | rc->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 1164 | rc->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
1201 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Shutting down testbed due to timeout while setup.\n")); | 1165 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Shutting down testbed due to timeout while setup.\n")); |
1202 | shutdown_now (rc); | 1166 | GNUNET_SCHEDULER_shutdown (); |
1203 | if (NULL != rc->test_master) | 1167 | if (NULL != rc->test_master) |
1204 | rc->test_master (rc->test_master_cls, 0, NULL, 0, 0); | 1168 | rc->test_master (rc->test_master_cls, 0, NULL, 0, 0); |
1205 | rc->test_master = NULL; | 1169 | rc->test_master = NULL; |