diff options
author | Nathan S. Evans <evans@in.tum.de> | 2010-11-05 18:21:50 +0000 |
---|---|---|
committer | Nathan S. Evans <evans@in.tum.de> | 2010-11-05 18:21:50 +0000 |
commit | 75a33a1499cf60ea4364c9aa673816629a6c1413 (patch) | |
tree | 0620da4312bb04de4d7b65074fdd3b0c3dd6cc0e /src/dv/test_transport_api_dv.c | |
parent | 7217c601ad30760872823193d62307e7a335d226 (diff) | |
download | gnunet-75a33a1499cf60ea4364c9aa673816629a6c1413.tar.gz gnunet-75a33a1499cf60ea4364c9aa673816629a6c1413.zip |
big scheduler refactoring, expect some issues
Diffstat (limited to 'src/dv/test_transport_api_dv.c')
-rw-r--r-- | src/dv/test_transport_api_dv.c | 103 |
1 files changed, 43 insertions, 60 deletions
diff --git a/src/dv/test_transport_api_dv.c b/src/dv/test_transport_api_dv.c index d38f378ba..f53aa48f9 100644 --- a/src/dv/test_transport_api_dv.c +++ b/src/dv/test_transport_api_dv.c | |||
@@ -75,8 +75,6 @@ static unsigned long long peers_left; | |||
75 | 75 | ||
76 | static struct GNUNET_TESTING_PeerGroup *pg; | 76 | static struct GNUNET_TESTING_PeerGroup *pg; |
77 | 77 | ||
78 | static struct GNUNET_SCHEDULER_Handle *sched; | ||
79 | |||
80 | const struct GNUNET_CONFIGURATION_Handle *main_cfg; | 78 | const struct GNUNET_CONFIGURATION_Handle *main_cfg; |
81 | 79 | ||
82 | GNUNET_SCHEDULER_TaskIdentifier die_task; | 80 | GNUNET_SCHEDULER_TaskIdentifier die_task; |
@@ -231,7 +229,7 @@ finish_testing () | |||
231 | pos = pos->next; | 229 | pos = pos->next; |
232 | if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK) | 230 | if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK) |
233 | { | 231 | { |
234 | GNUNET_SCHEDULER_cancel(sched, free_pos->disconnect_task); | 232 | GNUNET_SCHEDULER_cancel(free_pos->disconnect_task); |
235 | } | 233 | } |
236 | GNUNET_free(free_pos); | 234 | GNUNET_free(free_pos); |
237 | } | 235 | } |
@@ -253,7 +251,7 @@ finish_testing () | |||
253 | pos = pos->next; | 251 | pos = pos->next; |
254 | if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK) | 252 | if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK) |
255 | { | 253 | { |
256 | GNUNET_SCHEDULER_cancel(sched, free_pos->disconnect_task); | 254 | GNUNET_SCHEDULER_cancel(free_pos->disconnect_task); |
257 | } | 255 | } |
258 | GNUNET_free(free_pos); | 256 | GNUNET_free(free_pos); |
259 | } | 257 | } |
@@ -364,7 +362,7 @@ end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
364 | pos = pos->next; | 362 | pos = pos->next; |
365 | if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK) | 363 | if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK) |
366 | { | 364 | { |
367 | GNUNET_SCHEDULER_cancel(sched, free_pos->disconnect_task); | 365 | GNUNET_SCHEDULER_cancel(free_pos->disconnect_task); |
368 | } | 366 | } |
369 | GNUNET_free(free_pos); | 367 | GNUNET_free(free_pos); |
370 | } | 368 | } |
@@ -423,28 +421,27 @@ process_mtype (void *cls, | |||
423 | 421 | ||
424 | if ((total_messages_received == expected_messages) && (total_other_messages == 0)) | 422 | if ((total_messages_received == expected_messages) && (total_other_messages == 0)) |
425 | { | 423 | { |
426 | GNUNET_SCHEDULER_cancel (sched, die_task); | 424 | GNUNET_SCHEDULER_cancel (die_task); |
427 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | 425 | die_task = GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, |
428 | TEST_TIMEOUT, | ||
429 | &end_badly, "waiting for DV peers to connect!"); | 426 | &end_badly, "waiting for DV peers to connect!"); |
430 | /* | 427 | /* |
431 | if ((num_peers == 3) && (total_other_expected_messages == 2)) | 428 | if ((num_peers == 3) && (total_other_expected_messages == 2)) |
432 | { | 429 | { |
433 | GNUNET_SCHEDULER_add_now (sched, &send_other_messages, NULL); | 430 | GNUNET_SCHEDULER_add_now (&send_other_messages, NULL); |
434 | } | 431 | } |
435 | else | 432 | else |
436 | { | 433 | { |
437 | GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20), &send_other_messages, NULL); | 434 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20), &send_other_messages, NULL); |
438 | }*/ | 435 | }*/ |
439 | } | 436 | } |
440 | else if ((total_other_expected_messages > 0) && (total_other_messages == total_other_expected_messages)) | 437 | else if ((total_other_expected_messages > 0) && (total_other_messages == total_other_expected_messages)) |
441 | { | 438 | { |
442 | GNUNET_SCHEDULER_cancel (sched, die_task); | 439 | GNUNET_SCHEDULER_cancel (die_task); |
443 | GNUNET_SCHEDULER_add_now (sched, &finish_testing, NULL); | 440 | GNUNET_SCHEDULER_add_now (&finish_testing, NULL); |
444 | } | 441 | } |
445 | else | 442 | else |
446 | { | 443 | { |
447 | pos->disconnect_task = GNUNET_SCHEDULER_add_now(sched, &disconnect_cores, pos); | 444 | pos->disconnect_task = GNUNET_SCHEDULER_add_now(&disconnect_cores, pos); |
448 | } | 445 | } |
449 | 446 | ||
450 | return GNUNET_OK; | 447 | return GNUNET_OK; |
@@ -531,8 +528,7 @@ init_notify_peer1 (void *cls, | |||
531 | /* | 528 | /* |
532 | * Connect to the receiving peer | 529 | * Connect to the receiving peer |
533 | */ | 530 | */ |
534 | pos->peer2handle = GNUNET_CORE_connect (sched, | 531 | pos->peer2handle = GNUNET_CORE_connect (pos->peer2->cfg, |
535 | pos->peer2->cfg, | ||
536 | TIMEOUT, | 532 | TIMEOUT, |
537 | pos, | 533 | pos, |
538 | &init_notify_peer2, | 534 | &init_notify_peer2, |
@@ -554,14 +550,13 @@ send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
554 | 550 | ||
555 | if (die_task == GNUNET_SCHEDULER_NO_TASK) | 551 | if (die_task == GNUNET_SCHEDULER_NO_TASK) |
556 | { | 552 | { |
557 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | 553 | die_task = GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, |
558 | TEST_TIMEOUT, | ||
559 | &end_badly, "from create topology (timeout)"); | 554 | &end_badly, "from create topology (timeout)"); |
560 | } | 555 | } |
561 | 556 | ||
562 | if (total_server_connections >= MAX_OUTSTANDING_CONNECTIONS) | 557 | if (total_server_connections >= MAX_OUTSTANDING_CONNECTIONS) |
563 | { | 558 | { |
564 | GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1), | 559 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1), |
565 | &send_test_messages, pos); | 560 | &send_test_messages, pos); |
566 | return; /* Otherwise we'll double schedule messages here! */ | 561 | return; /* Otherwise we'll double schedule messages here! */ |
567 | } | 562 | } |
@@ -571,8 +566,7 @@ send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
571 | /* | 566 | /* |
572 | * Connect to the sending peer | 567 | * Connect to the sending peer |
573 | */ | 568 | */ |
574 | pos->peer1handle = GNUNET_CORE_connect (sched, | 569 | pos->peer1handle = GNUNET_CORE_connect (pos->peer1->cfg, |
575 | pos->peer1->cfg, | ||
576 | TIMEOUT, | 570 | TIMEOUT, |
577 | pos, | 571 | pos, |
578 | &init_notify_peer1, | 572 | &init_notify_peer1, |
@@ -585,12 +579,11 @@ send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
585 | 579 | ||
586 | if (total_server_connections < MAX_OUTSTANDING_CONNECTIONS) | 580 | if (total_server_connections < MAX_OUTSTANDING_CONNECTIONS) |
587 | { | 581 | { |
588 | GNUNET_SCHEDULER_add_now (sched, | 582 | GNUNET_SCHEDULER_add_now (&send_test_messages, pos->next); |
589 | &send_test_messages, pos->next); | ||
590 | } | 583 | } |
591 | else | 584 | else |
592 | { | 585 | { |
593 | GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1), | 586 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1), |
594 | &send_test_messages, pos->next); | 587 | &send_test_messages, pos->next); |
595 | } | 588 | } |
596 | } | 589 | } |
@@ -652,7 +645,7 @@ send_other_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
652 | pos = pos->next; | 645 | pos = pos->next; |
653 | if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK) | 646 | if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK) |
654 | { | 647 | { |
655 | GNUNET_SCHEDULER_cancel(sched, free_pos->disconnect_task); | 648 | GNUNET_SCHEDULER_cancel(free_pos->disconnect_task); |
656 | } | 649 | } |
657 | GNUNET_free(free_pos); | 650 | GNUNET_free(free_pos); |
658 | } | 651 | } |
@@ -661,15 +654,15 @@ send_other_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) | |||
661 | total_other_expected_messages = temp_total_other_messages; | 654 | total_other_expected_messages = temp_total_other_messages; |
662 | if (total_other_expected_messages == 0) | 655 | if (total_other_expected_messages == 0) |
663 | { | 656 | { |
664 | GNUNET_SCHEDULER_add_now (sched, &end_badly, "send_other_messages had 0 messages to send, no DV connections made!"); | 657 | GNUNET_SCHEDULER_add_now (&end_badly, "send_other_messages had 0 messages to send, no DV connections made!"); |
665 | } | 658 | } |
666 | #if VERBOSE | 659 | #if VERBOSE |
667 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Preparing to send %d other test messages\n", total_other_expected_messages); | 660 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Preparing to send %d other test messages\n", total_other_expected_messages); |
668 | #endif | 661 | #endif |
669 | 662 | ||
670 | GNUNET_SCHEDULER_add_now (sched, &send_test_messages, other_test_messages); | 663 | GNUNET_SCHEDULER_add_now (&send_test_messages, other_test_messages); |
671 | GNUNET_SCHEDULER_cancel(sched, die_task); | 664 | GNUNET_SCHEDULER_cancel(die_task); |
672 | die_task = GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 250), &end_badly, "from send_other_messages"); | 665 | die_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 250), &end_badly, "from send_other_messages"); |
673 | } | 666 | } |
674 | 667 | ||
675 | void | 668 | void |
@@ -722,23 +715,22 @@ topology_callback (void *cls, | |||
722 | total_connections); | 715 | total_connections); |
723 | #endif | 716 | #endif |
724 | 717 | ||
725 | GNUNET_SCHEDULER_cancel (sched, die_task); | 718 | GNUNET_SCHEDULER_cancel (die_task); |
726 | die_task = GNUNET_SCHEDULER_NO_TASK; | 719 | die_task = GNUNET_SCHEDULER_NO_TASK; |
727 | GNUNET_SCHEDULER_add_now (sched, &send_test_messages, test_messages); | 720 | GNUNET_SCHEDULER_add_now (&send_test_messages, test_messages); |
728 | } | 721 | } |
729 | else if (total_connections + failed_connections == expected_connections) | 722 | else if (total_connections + failed_connections == expected_connections) |
730 | { | 723 | { |
731 | if (failed_connections < (unsigned int)(fail_percentage * total_connections)) | 724 | if (failed_connections < (unsigned int)(fail_percentage * total_connections)) |
732 | { | 725 | { |
733 | GNUNET_SCHEDULER_cancel (sched, die_task); | 726 | GNUNET_SCHEDULER_cancel (die_task); |
734 | die_task = GNUNET_SCHEDULER_NO_TASK; | 727 | die_task = GNUNET_SCHEDULER_NO_TASK; |
735 | GNUNET_SCHEDULER_add_now (sched, &send_test_messages, test_messages); | 728 | GNUNET_SCHEDULER_add_now (&send_test_messages, test_messages); |
736 | } | 729 | } |
737 | else | 730 | else |
738 | { | 731 | { |
739 | GNUNET_SCHEDULER_cancel (sched, die_task); | 732 | GNUNET_SCHEDULER_cancel (die_task); |
740 | die_task = GNUNET_SCHEDULER_add_now (sched, | 733 | die_task = GNUNET_SCHEDULER_add_now (&end_badly, "from topology_callback (too many failed connections)"); |
741 | &end_badly, "from topology_callback (too many failed connections)"); | ||
742 | } | 734 | } |
743 | } | 735 | } |
744 | else | 736 | else |
@@ -764,15 +756,13 @@ connect_topology () | |||
764 | #endif | 756 | #endif |
765 | } | 757 | } |
766 | 758 | ||
767 | GNUNET_SCHEDULER_cancel (sched, die_task); | 759 | GNUNET_SCHEDULER_cancel (die_task); |
768 | if (expected_connections == GNUNET_SYSERR) | 760 | if (expected_connections == GNUNET_SYSERR) |
769 | { | 761 | { |
770 | die_task = GNUNET_SCHEDULER_add_now (sched, | 762 | die_task = GNUNET_SCHEDULER_add_now (&end_badly, "from connect topology (bad return)"); |
771 | &end_badly, "from connect topology (bad return)"); | ||
772 | } | 763 | } |
773 | 764 | ||
774 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | 765 | die_task = GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, |
775 | TEST_TIMEOUT, | ||
776 | &end_badly, "from connect topology (timeout)"); | 766 | &end_badly, "from connect topology (timeout)"); |
777 | } | 767 | } |
778 | 768 | ||
@@ -790,13 +780,11 @@ create_topology () | |||
790 | } | 780 | } |
791 | else | 781 | else |
792 | { | 782 | { |
793 | GNUNET_SCHEDULER_cancel (sched, die_task); | 783 | GNUNET_SCHEDULER_cancel (die_task); |
794 | die_task = GNUNET_SCHEDULER_add_now (sched, | 784 | die_task = GNUNET_SCHEDULER_add_now (&end_badly, "from create topology (bad return)"); |
795 | &end_badly, "from create topology (bad return)"); | ||
796 | } | 785 | } |
797 | GNUNET_SCHEDULER_cancel (sched, die_task); | 786 | GNUNET_SCHEDULER_cancel (die_task); |
798 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | 787 | die_task = GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, |
799 | TEST_TIMEOUT, | ||
800 | &end_badly, "from continue startup (timeout)"); | 788 | &end_badly, "from continue startup (timeout)"); |
801 | } | 789 | } |
802 | 790 | ||
@@ -867,7 +855,7 @@ static void all_connect_handler (void *cls, | |||
867 | 855 | ||
868 | if (temp_total_other_messages == num_additional_messages) | 856 | if (temp_total_other_messages == num_additional_messages) |
869 | { | 857 | { |
870 | GNUNET_SCHEDULER_add_now (sched, &send_other_messages, NULL); | 858 | GNUNET_SCHEDULER_add_now (&send_other_messages, NULL); |
871 | } | 859 | } |
872 | } | 860 | } |
873 | 861 | ||
@@ -892,7 +880,7 @@ peers_started_callback (void *cls, | |||
892 | GNUNET_assert(GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_put(peer_daemon_hash, &id->hashPubKey, d, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 880 | GNUNET_assert(GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_put(peer_daemon_hash, &id->hashPubKey, d, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
893 | 881 | ||
894 | new_peer = GNUNET_malloc(sizeof(struct PeerContext)); | 882 | new_peer = GNUNET_malloc(sizeof(struct PeerContext)); |
895 | new_peer->peer_handle = GNUNET_CORE_connect(sched, cfg, GNUNET_TIME_UNIT_FOREVER_REL, d, NULL, &all_connect_handler, NULL, NULL, NULL, GNUNET_NO, NULL, GNUNET_NO, no_handlers); | 883 | new_peer->peer_handle = GNUNET_CORE_connect(cfg, GNUNET_TIME_UNIT_FOREVER_REL, d, NULL, &all_connect_handler, NULL, NULL, NULL, GNUNET_NO, NULL, GNUNET_NO, no_handlers); |
896 | new_peer->daemon = d; | 884 | new_peer->daemon = d; |
897 | new_peer->next = all_peers; | 885 | new_peer->next = all_peers; |
898 | all_peers = new_peer; | 886 | all_peers = new_peer; |
@@ -905,11 +893,10 @@ peers_started_callback (void *cls, | |||
905 | "All %d daemons started, now creating topology!\n", | 893 | "All %d daemons started, now creating topology!\n", |
906 | num_peers); | 894 | num_peers); |
907 | #endif | 895 | #endif |
908 | GNUNET_SCHEDULER_cancel (sched, die_task); | 896 | GNUNET_SCHEDULER_cancel (die_task); |
909 | /* Set up task in case topology creation doesn't finish | 897 | /* Set up task in case topology creation doesn't finish |
910 | * within a reasonable amount of time */ | 898 | * within a reasonable amount of time */ |
911 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | 899 | die_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply |
912 | GNUNET_TIME_relative_multiply | ||
913 | (GNUNET_TIME_UNIT_MINUTES, 5), | 900 | (GNUNET_TIME_UNIT_MINUTES, 5), |
914 | &end_badly, "from peers_started_callback"); | 901 | &end_badly, "from peers_started_callback"); |
915 | 902 | ||
@@ -949,21 +936,19 @@ void hostkey_callback (void *cls, | |||
949 | "All %d hostkeys created, now creating topology!\n", | 936 | "All %d hostkeys created, now creating topology!\n", |
950 | num_peers); | 937 | num_peers); |
951 | #endif | 938 | #endif |
952 | GNUNET_SCHEDULER_cancel (sched, die_task); | 939 | GNUNET_SCHEDULER_cancel (die_task); |
953 | /* Set up task in case topology creation doesn't finish | 940 | /* Set up task in case topology creation doesn't finish |
954 | * within a reasonable amount of time */ | 941 | * within a reasonable amount of time */ |
955 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | 942 | die_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply |
956 | GNUNET_TIME_relative_multiply | ||
957 | (GNUNET_TIME_UNIT_MINUTES, 5), | 943 | (GNUNET_TIME_UNIT_MINUTES, 5), |
958 | &end_badly, "from hostkey_callback"); | 944 | &end_badly, "from hostkey_callback"); |
959 | GNUNET_SCHEDULER_add_now(sched, &create_topology, NULL); | 945 | GNUNET_SCHEDULER_add_now(&create_topology, NULL); |
960 | ok = 0; | 946 | ok = 0; |
961 | } | 947 | } |
962 | } | 948 | } |
963 | 949 | ||
964 | static void | 950 | static void |
965 | run (void *cls, | 951 | run (void *cls, |
966 | struct GNUNET_SCHEDULER_Handle *s, | ||
967 | char *const *args, | 952 | char *const *args, |
968 | const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) | 953 | const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) |
969 | { | 954 | { |
@@ -972,7 +957,6 @@ run (void *cls, | |||
972 | char * blacklist_topology_str; | 957 | char * blacklist_topology_str; |
973 | char * connect_topology_option_str; | 958 | char * connect_topology_option_str; |
974 | char * connect_topology_option_modifier_string; | 959 | char * connect_topology_option_modifier_string; |
975 | sched = s; | ||
976 | ok = 1; | 960 | ok = 1; |
977 | 961 | ||
978 | dotOutFile = fopen (dotOutFileName, "w"); | 962 | dotOutFile = fopen (dotOutFileName, "w"); |
@@ -1062,13 +1046,12 @@ run (void *cls, | |||
1062 | peers_left = num_peers; | 1046 | peers_left = num_peers; |
1063 | 1047 | ||
1064 | /* Set up a task to end testing if peer start fails */ | 1048 | /* Set up a task to end testing if peer start fails */ |
1065 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | 1049 | die_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply |
1066 | GNUNET_TIME_relative_multiply | ||
1067 | (GNUNET_TIME_UNIT_MINUTES, 5), | 1050 | (GNUNET_TIME_UNIT_MINUTES, 5), |
1068 | &end_badly, "didn't start all daemons in reasonable amount of time!!!"); | 1051 | &end_badly, "didn't start all daemons in reasonable amount of time!!!"); |
1069 | 1052 | ||
1070 | peer_daemon_hash = GNUNET_CONTAINER_multihashmap_create(peers_left); | 1053 | peer_daemon_hash = GNUNET_CONTAINER_multihashmap_create(peers_left); |
1071 | pg = GNUNET_TESTING_daemons_start (sched, cfg, | 1054 | pg = GNUNET_TESTING_daemons_start (cfg, |
1072 | peers_left, TIMEOUT, &hostkey_callback, NULL, &peers_started_callback, NULL, | 1055 | peers_left, TIMEOUT, &hostkey_callback, NULL, &peers_started_callback, NULL, |
1073 | &topology_callback, NULL, NULL); | 1056 | &topology_callback, NULL, NULL); |
1074 | 1057 | ||