aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlurchi <lurchi@strangeplace.net>2017-08-13 21:04:34 +0200
committerlurchi <lurchi@strangeplace.net>2017-08-13 21:04:34 +0200
commita4cf7b69030ba9ded923828a781a65f62e5dc616 (patch)
tree8c55491dc44b14c59a96f23d0d451aa0e983485a /src
parent70fedfb249696028103dd77f5641f8f7b46f5c61 (diff)
downloadgnunet-a4cf7b69030ba9ded923828a781a65f62e5dc616.tar.gz
gnunet-a4cf7b69030ba9ded923828a781a65f62e5dc616.zip
reimplement init_fd_info as preparation for refactoring GNUNET_SCHEDULER_add_select
Diffstat (limited to 'src')
-rw-r--r--src/util/scheduler.c282
1 files changed, 206 insertions, 76 deletions
diff --git a/src/util/scheduler.c b/src/util/scheduler.c
index 2ea2378eb..c4017f23b 100644
--- a/src/util/scheduler.c
+++ b/src/util/scheduler.c
@@ -484,6 +484,7 @@ GNUNET_SCHEDULER_shutdown ()
484static void 484static void
485destroy_task (struct GNUNET_SCHEDULER_Task *t) 485destroy_task (struct GNUNET_SCHEDULER_Task *t)
486{ 486{
487 // FIXME: destroy fds!
487 if (NULL != t->read_set) 488 if (NULL != t->read_set)
488 GNUNET_NETWORK_fdset_destroy (t->read_set); 489 GNUNET_NETWORK_fdset_destroy (t->read_set);
489 if (NULL != t->write_set) 490 if (NULL != t->write_set)
@@ -587,6 +588,7 @@ sighandler_shutdown ()
587 * @return #GNUNET_YES if tasks which prevent shutdown exist 588 * @return #GNUNET_YES if tasks which prevent shutdown exist
588 * #GNUNET_NO if the system has initiated shutdown 589 * #GNUNET_NO if the system has initiated shutdown
589 */ 590 */
591// FIXME: make it an internal function again
590int 592int
591GNUNET_SCHEDULER_check_lifeness () 593GNUNET_SCHEDULER_check_lifeness ()
592{ 594{
@@ -606,6 +608,8 @@ GNUNET_SCHEDULER_check_lifeness ()
606 if (NULL != shutdown_head) 608 if (NULL != shutdown_head)
607 { 609 {
608 GNUNET_SCHEDULER_shutdown (); 610 GNUNET_SCHEDULER_shutdown ();
611 LOG (GNUNET_ERROR_TYPE_WARNING,
612 "shutting down\n");
609 scheduler_driver->set_wakeup (scheduler_driver->cls, 613 scheduler_driver->set_wakeup (scheduler_driver->cls,
610 GNUNET_TIME_absolute_get ()); 614 GNUNET_TIME_absolute_get ());
611 return GNUNET_YES; 615 return GNUNET_YES;
@@ -691,84 +695,173 @@ GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p)
691 695
692void 696void
693init_fd_info (struct GNUNET_SCHEDULER_Task *t, 697init_fd_info (struct GNUNET_SCHEDULER_Task *t,
694 const struct GNUNET_NETWORK_Handle *read_nh, 698 const struct GNUNET_NETWORK_Handle **read_nh,
695 const struct GNUNET_NETWORK_Handle *write_nh, 699 size_t read_nh_len,
696 const struct GNUNET_DISK_FileHandle *read_fh, 700 const struct GNUNET_NETWORK_Handle **write_nh,
697 const struct GNUNET_DISK_FileHandle *write_fh) 701 size_t write_nh_len,
702 const struct GNUNET_DISK_FileHandle **read_fh,
703 size_t read_fh_len,
704 const struct GNUNET_DISK_FileHandle **write_fh,
705 size_t write_fh_len)
698{ 706{
699 // either only network handles or only file handles are allowed 707 struct GNUNET_SCHEDULER_FdInfo *fdi;
700 GNUNET_assert (!((NULL != read_nh || NULL != write_nh) && (NULL != read_fh || NULL != write_fh)));
701 708
702 if (NULL != read_nh && NULL != write_nh) 709 t->fds_len = read_nh_len + write_nh_len + read_fh_len + write_fh_len;
703 { 710 if (1 == t->fds_len)
704 int read_fd = GNUNET_NETWORK_get_fd (read_nh);
705 int write_fd = GNUNET_NETWORK_get_fd (write_nh);
706 t->read_fd = read_fd;
707 t->write_fd = write_fd;
708 struct GNUNET_SCHEDULER_FdInfo *fds = GNUNET_new_array (2, struct GNUNET_SCHEDULER_FdInfo);
709 struct GNUNET_SCHEDULER_FdInfo read_fdi = {.fd = read_nh, .et = GNUNET_SCHEDULER_ET_IN, .sock = read_fd};
710 struct GNUNET_SCHEDULER_FdInfo write_fdi = {.fd = write_nh, .et = GNUNET_SCHEDULER_ET_OUT, .sock = write_fd};
711 fds[0] = read_fdi;
712 fds[1] = write_fdi;
713 t->fds = fds;
714 t->fds_len = 2;
715 }
716 else if (NULL != read_fh && NULL != write_fh)
717 {
718 int read_fd = read_fh->fd;
719 int write_fd = write_fh->fd;
720 struct GNUNET_SCHEDULER_FdInfo *fds = GNUNET_new_array (2, struct GNUNET_SCHEDULER_FdInfo);
721 struct GNUNET_SCHEDULER_FdInfo read_fdi = {.fh = read_fh, .et = GNUNET_SCHEDULER_ET_IN, .sock = read_fd};
722 struct GNUNET_SCHEDULER_FdInfo write_fdi = {.fh = write_fh, .et = GNUNET_SCHEDULER_ET_OUT, .sock = write_fd};
723 t->read_fd = read_fd;
724 t->write_fd = write_fd;
725 fds[0] = read_fdi;
726 fds[1] = write_fdi;
727 t->fds = fds;
728 t->fds_len = 2;
729 }
730 else if (NULL != read_nh)
731 { 711 {
732 int read_fd = GNUNET_NETWORK_get_fd (read_nh); 712 fdi = &t->fdx;
733 struct GNUNET_SCHEDULER_FdInfo read_fdi = {.fd = read_nh, .et = GNUNET_SCHEDULER_ET_IN, .sock = read_fd}; 713 t->fds = fdi;
734 t->read_fd = read_fd; 714 if (1 == read_nh_len)
735 t->write_fd = -1; 715 {
736 t->fdx = read_fdi; 716 fdi->fd = *read_nh;
737 t->fds = &t->fdx; 717 fdi->et = GNUNET_SCHEDULER_ET_IN;
738 t->fds_len = 1; 718 fdi->sock = GNUNET_NETWORK_get_fd (*read_nh);
719 t->read_fd = fdi->sock;
720 t->write_fd = -1;
721 }
722 else if (1 == write_nh_len)
723 {
724 fdi->fd = *write_nh;
725 fdi->et = GNUNET_SCHEDULER_ET_OUT;
726 fdi->sock = GNUNET_NETWORK_get_fd (*write_nh);
727 t->read_fd = -1;
728 t->write_fd = fdi->sock;
729 }
730 else if (1 == read_fh_len)
731 {
732 fdi->fh = *read_fh;
733 fdi->et = GNUNET_SCHEDULER_ET_IN;
734 fdi->sock = (*read_fh)->fd; // FIXME: does not work under WIN32
735 t->read_fd = fdi->sock;
736 t->write_fd = -1;
737 }
738 else
739 {
740 fdi->fh = *write_fh;
741 fdi->et = GNUNET_SCHEDULER_ET_OUT;
742 fdi->sock = (*write_fh)->fd; // FIXME: does not work under WIN32
743 t->read_fd = -1;
744 t->write_fd = fdi->sock;
745 }
739 } 746 }
740 else if (NULL != write_nh) 747 else
741 { 748 {
742 int write_fd = GNUNET_NETWORK_get_fd (write_nh); 749 fdi = GNUNET_new_array (t->fds_len, struct GNUNET_SCHEDULER_FdInfo);
743 struct GNUNET_SCHEDULER_FdInfo write_fdi = {.fd = write_nh, .et = GNUNET_SCHEDULER_ET_OUT, .sock = write_fd}; 750 t->fds = fdi;
744 t->read_fd = -1; 751 t->read_fd = -1;
745 t->write_fd = write_fd;
746 t->fdx = write_fdi;
747 t->fds = &t->fdx;
748 t->fds_len = 1;
749 }
750 else if (NULL != read_fh)
751 {
752 int read_fd = read_fh->fd;
753 struct GNUNET_SCHEDULER_FdInfo read_fdi = {.fh = read_fh, .et = GNUNET_SCHEDULER_ET_IN, .sock = read_fd};
754 t->read_fd = read_fd;
755 t->write_fd = -1; 752 t->write_fd = -1;
756 t->fdx = read_fdi; 753 size_t i;
757 t->fds = &t->fdx; 754 for (i = 0; i != read_nh_len; ++i)
758 t->fds_len = 1; 755 {
759 } 756 fdi->fd = read_nh[i];
760 else if (NULL != write_fh) 757 fdi->et = GNUNET_SCHEDULER_ET_IN;
761 { 758 fdi->sock = GNUNET_NETWORK_get_fd (read_nh[i]);
762 int write_fd = write_fh->fd; 759 ++fdi;
763 struct GNUNET_SCHEDULER_FdInfo write_fdi = {.fh = write_fh, .et = GNUNET_SCHEDULER_ET_OUT, .sock = write_fd}; 760 }
764 t->read_fd = -1; 761 for (i = 0; i != write_nh_len; ++i)
765 t->write_fd = write_fd; 762 {
766 t->fdx = write_fdi; 763 fdi->fd = write_nh[i];
767 t->fds = &t->fdx; 764 fdi->et = GNUNET_SCHEDULER_ET_OUT;
768 t->fds_len = 1; 765 fdi->sock = GNUNET_NETWORK_get_fd (write_nh[i]);
766 ++fdi;
767 }
768 for (i = 0; i != read_fh_len; ++i)
769 {
770 fdi->fh = read_fh[i];
771 fdi->et = GNUNET_SCHEDULER_ET_IN;
772 fdi->sock = (read_fh[i])->fd; // FIXME: does not work under WIN32
773 ++fdi;
774 }
775 for (i = 0; i != write_fh_len; ++i)
776 {
777 fdi->fh = write_fh[i];
778 fdi->et = GNUNET_SCHEDULER_ET_OUT;
779 fdi->sock = (write_fh[i])->fd; // FIXME: does not work under WIN32
780 ++fdi;
781 }
769 } 782 }
770} 783}
771 784
785//void
786//init_fd_info (struct GNUNET_SCHEDULER_Task *t,
787// const struct GNUNET_NETWORK_Handle *read_nh,
788// const struct GNUNET_NETWORK_Handle *write_nh,
789// const struct GNUNET_DISK_FileHandle *read_fh,
790// const struct GNUNET_DISK_FileHandle *write_fh)
791//{
792// // either only network handles or only file handles are allowed
793// GNUNET_assert (!((NULL != read_nh || NULL != write_nh) && (NULL != read_fh || NULL != write_fh)));
794//
795// if (NULL != read_nh && NULL != write_nh)
796// {
797// int read_fd = GNUNET_NETWORK_get_fd (read_nh);
798// int write_fd = GNUNET_NETWORK_get_fd (write_nh);
799// t->read_fd = read_fd;
800// t->write_fd = write_fd;
801// struct GNUNET_SCHEDULER_FdInfo *fds = GNUNET_new_array (2, struct GNUNET_SCHEDULER_FdInfo);
802// struct GNUNET_SCHEDULER_FdInfo read_fdi = {.fd = read_nh, .et = GNUNET_SCHEDULER_ET_IN, .sock = read_fd};
803// struct GNUNET_SCHEDULER_FdInfo write_fdi = {.fd = write_nh, .et = GNUNET_SCHEDULER_ET_OUT, .sock = write_fd};
804// fds[0] = read_fdi;
805// fds[1] = write_fdi;
806// t->fds = fds;
807// t->fds_len = 2;
808// }
809// else if (NULL != read_fh && NULL != write_fh)
810// {
811// int read_fd = read_fh->fd;
812// int write_fd = write_fh->fd;
813// struct GNUNET_SCHEDULER_FdInfo *fds = GNUNET_new_array (2, struct GNUNET_SCHEDULER_FdInfo);
814// struct GNUNET_SCHEDULER_FdInfo read_fdi = {.fh = read_fh, .et = GNUNET_SCHEDULER_ET_IN, .sock = read_fd};
815// struct GNUNET_SCHEDULER_FdInfo write_fdi = {.fh = write_fh, .et = GNUNET_SCHEDULER_ET_OUT, .sock = write_fd};
816// t->read_fd = read_fd;
817// t->write_fd = write_fd;
818// fds[0] = read_fdi;
819// fds[1] = write_fdi;
820// t->fds = fds;
821// t->fds_len = 2;
822// }
823// else if (NULL != read_nh)
824// {
825// int read_fd = GNUNET_NETWORK_get_fd (read_nh);
826// struct GNUNET_SCHEDULER_FdInfo read_fdi = {.fd = read_nh, .et = GNUNET_SCHEDULER_ET_IN, .sock = read_fd};
827// t->read_fd = read_fd;
828// t->write_fd = -1;
829// t->fdx = read_fdi;
830// t->fds = &t->fdx;
831// t->fds_len = 1;
832// }
833// else if (NULL != write_nh)
834// {
835// int write_fd = GNUNET_NETWORK_get_fd (write_nh);
836// struct GNUNET_SCHEDULER_FdInfo write_fdi = {.fd = write_nh, .et = GNUNET_SCHEDULER_ET_OUT, .sock = write_fd};
837// t->read_fd = -1;
838// t->write_fd = write_fd;
839// t->fdx = write_fdi;
840// t->fds = &t->fdx;
841// t->fds_len = 1;
842// }
843// else if (NULL != read_fh)
844// {
845// int read_fd = read_fh->fd;
846// struct GNUNET_SCHEDULER_FdInfo read_fdi = {.fh = read_fh, .et = GNUNET_SCHEDULER_ET_IN, .sock = read_fd};
847// t->read_fd = read_fd;
848// t->write_fd = -1;
849// t->fdx = read_fdi;
850// t->fds = &t->fdx;
851// t->fds_len = 1;
852// }
853// else if (NULL != write_fh)
854// {
855// int write_fd = write_fh->fd;
856// struct GNUNET_SCHEDULER_FdInfo write_fdi = {.fh = write_fh, .et = GNUNET_SCHEDULER_ET_OUT, .sock = write_fd};
857// t->read_fd = -1;
858// t->write_fd = write_fd;
859// t->fdx = write_fdi;
860// t->fds = &t->fdx;
861// t->fds_len = 1;
862// }
863//}
864
772 865
773void scheduler_multi_function_call(struct GNUNET_SCHEDULER_Task *t, int (*driver_func)()) 866void scheduler_multi_function_call(struct GNUNET_SCHEDULER_Task *t, int (*driver_func)())
774{ 867{
@@ -1262,11 +1355,25 @@ add_without_sets (struct GNUNET_TIME_Relative delay,
1262 void *task_cls) 1355 void *task_cls)
1263{ 1356{
1264 struct GNUNET_SCHEDULER_Task *t; 1357 struct GNUNET_SCHEDULER_Task *t;
1265 1358
1266 GNUNET_assert (NULL != active_task); 1359 GNUNET_assert (NULL != active_task);
1267 GNUNET_assert (NULL != task); 1360 GNUNET_assert (NULL != task);
1268 t = GNUNET_new (struct GNUNET_SCHEDULER_Task); 1361 t = GNUNET_new (struct GNUNET_SCHEDULER_Task);
1269 init_fd_info (t, read_nh, write_nh, read_fh, write_fh); 1362
1363 init_fd_info (t,
1364 &read_nh,
1365 read_nh ? 1 : 0,
1366 &write_nh,
1367 write_nh ? 1 : 0,
1368 &read_fh,
1369 read_fh ? 1 : 0,
1370 &write_fh,
1371 write_fh ? 1 : 0);
1372
1373 //int read_fds[2] = {GNUNET_NETWORK_get_fd (read_nh), read_fh->fd};
1374 //int write_fds[2] = {GNUNET_NETWORK_get_fd (write_nh), write_fh->fd};
1375 //init_fd_info (t, read_fds, 2, write_fds, 2);
1376 //init_fd_info (t, read_nh, write_nh, read_fh, write_fh);
1270 t->callback = task; 1377 t->callback = task;
1271 t->callback_cls = task_cls; 1378 t->callback_cls = task_cls;
1272#if DEBUG_FDS 1379#if DEBUG_FDS
@@ -1678,7 +1785,10 @@ GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task,
1678 (0 != (GNUNET_SCHEDULER_ET_OUT & et)) ) 1785 (0 != (GNUNET_SCHEDULER_ET_OUT & et)) )
1679 reason |= GNUNET_SCHEDULER_REASON_WRITE_READY; 1786 reason |= GNUNET_SCHEDULER_REASON_WRITE_READY;
1680 reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE; 1787 reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE;
1681 GNUNET_assert (1 == task->fds_len); 1788
1789
1790
1791
1682 task->reason = reason; 1792 task->reason = reason;
1683 task->fds = &task->fdx; // FIXME: if task contains a list of fds, this is wrong! 1793 task->fds = &task->fdx; // FIXME: if task contains a list of fds, this is wrong!
1684 task->fdx.et = et; 1794 task->fdx.et = et;
@@ -1709,6 +1819,7 @@ GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task,
1709int 1819int
1710GNUNET_SCHEDULER_run_from_driver (struct GNUNET_SCHEDULER_Handle *sh) 1820GNUNET_SCHEDULER_run_from_driver (struct GNUNET_SCHEDULER_Handle *sh)
1711{ 1821{
1822 // FIXME: call check_lifeness here!
1712 enum GNUNET_SCHEDULER_Priority p; 1823 enum GNUNET_SCHEDULER_Priority p;
1713 struct GNUNET_SCHEDULER_Task *pos; 1824 struct GNUNET_SCHEDULER_Task *pos;
1714 struct GNUNET_TIME_Absolute now; 1825 struct GNUNET_TIME_Absolute now;
@@ -1772,12 +1883,14 @@ GNUNET_SCHEDULER_run_from_driver (struct GNUNET_SCHEDULER_Handle *sh)
1772 GNUNET_NETWORK_fdset_zero (sh->ws); 1883 GNUNET_NETWORK_fdset_zero (sh->ws);
1773 tc.fds_len = pos->fds_len; 1884 tc.fds_len = pos->fds_len;
1774 tc.fds = pos->fds; 1885 tc.fds = pos->fds;
1775 tc.read_ready = (NULL == pos->read_set) ? sh->rs : pos->read_set; 1886 //tc.read_ready = (NULL == pos->read_set) ? sh->rs : pos->read_set;
1887 tc.read_ready = sh->rs;
1776 if ( (-1 != pos->read_fd) && 1888 if ( (-1 != pos->read_fd) &&
1777 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_READ_READY)) ) 1889 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_READ_READY)) )
1778 GNUNET_NETWORK_fdset_set_native (sh->rs, 1890 GNUNET_NETWORK_fdset_set_native (sh->rs,
1779 pos->read_fd); 1891 pos->read_fd);
1780 tc.write_ready = (NULL == pos->write_set) ? sh->ws : pos->write_set; 1892 //tc.write_ready = (NULL == pos->write_set) ? sh->ws : pos->write_set;
1893 tc.write_ready = sh->ws;
1781 if ( (-1 != pos->write_fd) && 1894 if ( (-1 != pos->write_fd) &&
1782 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ) 1895 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) )
1783 GNUNET_NETWORK_fdset_set_native (sh->ws, 1896 GNUNET_NETWORK_fdset_set_native (sh->ws,
@@ -2034,9 +2147,14 @@ select_loop (void *cls,
2034 last_tr = 0; 2147 last_tr = 0;
2035 busy_wait_warning = 0; 2148 busy_wait_warning = 0;
2036 // FIXME: remove check_lifeness, instead the condition should be: 2149 // FIXME: remove check_lifeness, instead the condition should be:
2037 // pending_in_head != NULL || pending_out_head != NULL || context->timeout > 0 2150 // pending_in_head != NULL || pending_out_head != NULL || tasks_ready
2038 while (GNUNET_YES == GNUNET_SCHEDULER_check_lifeness ()) 2151 while (GNUNET_YES == GNUNET_SCHEDULER_check_lifeness ())
2039 { 2152 {
2153 LOG (GNUNET_ERROR_TYPE_WARNING,
2154 "[%p] timeout = %s\n",
2155 sh,
2156 GNUNET_STRINGS_relative_time_to_string (context->timeout, GNUNET_NO));
2157
2040 GNUNET_NETWORK_fdset_zero (rs); 2158 GNUNET_NETWORK_fdset_zero (rs);
2041 GNUNET_NETWORK_fdset_zero (ws); 2159 GNUNET_NETWORK_fdset_zero (ws);
2042 struct Scheduled *pos; 2160 struct Scheduled *pos;
@@ -2083,6 +2201,7 @@ select_loop (void *cls,
2083#endif 2201#endif
2084#if DEBUG_FDS 2202#if DEBUG_FDS
2085 struct GNUNET_SCHEDULER_Task *t; 2203 struct GNUNET_SCHEDULER_Task *t;
2204 // FIXME: pending_head is a scheduler-internal variable!
2086 for (t = pending_head; NULL != t; t = t->next) 2205 for (t = pending_head; NULL != t; t = t->next)
2087 { 2206 {
2088 if (-1 != t->read_fd) 2207 if (-1 != t->read_fd)
@@ -2117,7 +2236,9 @@ select_loop (void *cls,
2117 (busy_wait_warning > 16) ) 2236 (busy_wait_warning > 16) )
2118 { 2237 {
2119 LOG (GNUNET_ERROR_TYPE_WARNING, 2238 LOG (GNUNET_ERROR_TYPE_WARNING,
2120 "Looks like we're busy waiting...\n"); 2239 "[%p] Looks like we're busy waiting...\n",
2240 sh);
2241 GNUNET_assert (0);
2121 short_wait (100); /* mitigate */ 2242 short_wait (100); /* mitigate */
2122 } 2243 }
2123 for (pos = context->scheduled_in_head; NULL != pos; pos = pos->next) 2244 for (pos = context->scheduled_in_head; NULL != pos; pos = pos->next)
@@ -2140,9 +2261,18 @@ select_loop (void *cls,
2140 GNUNET_SCHEDULER_task_ready (pos->task, GNUNET_SCHEDULER_ET_OUT); 2261 GNUNET_SCHEDULER_task_ready (pos->task, GNUNET_SCHEDULER_ET_OUT);
2141 } 2262 }
2142 } 2263 }
2143 GNUNET_SCHEDULER_run_from_driver (sh); 2264 int tasks_ready = GNUNET_SCHEDULER_run_from_driver (sh);
2265 LOG (GNUNET_ERROR_TYPE_WARNING,
2266 "[%p] tasks_ready: %d\n",
2267 sh,
2268 tasks_ready);
2269 // FIXME: tasks_run is a driver-internal variable! Instead we should increment
2270 // a local variable tasks_ready_count everytime we're calling GNUNET_SCHEDULER_task_ready.
2144 if (last_tr == tasks_run) 2271 if (last_tr == tasks_run)
2145 { 2272 {
2273 LOG (GNUNET_ERROR_TYPE_WARNING,
2274 "[%p] no tasks run\n",
2275 sh);
2146 short_wait (1); 2276 short_wait (1);
2147 busy_wait_warning++; 2277 busy_wait_warning++;
2148 } 2278 }