aboutsummaryrefslogtreecommitdiff
path: root/src/util/scheduler.c
diff options
context:
space:
mode:
authort3sserakt <t3ss@posteo.de>2017-07-20 15:23:36 +0200
committert3sserakt <t3ss@posteo.de>2017-07-20 15:23:36 +0200
commita9d92c556d88da778dcde68114cd21b36d6db539 (patch)
tree33f504e82d42c1f7c5aea18e4a709377d2012e5c /src/util/scheduler.c
parent6d96643709856bd59c47e7cca2b40636435a40f8 (diff)
downloadgnunet-a9d92c556d88da778dcde68114cd21b36d6db539.tar.gz
gnunet-a9d92c556d88da778dcde68114cd21b36d6db539.zip
started further refactoring of scheduler. ATTENTION, actual Status does not compile!
Diffstat (limited to 'src/util/scheduler.c')
-rw-r--r--src/util/scheduler.c417
1 files changed, 264 insertions, 153 deletions
diff --git a/src/util/scheduler.c b/src/util/scheduler.c
index a7b1d8e2a..e27eb0fe0 100644
--- a/src/util/scheduler.c
+++ b/src/util/scheduler.c
@@ -73,7 +73,7 @@
73 * Argument to be passed from the driver to 73 * Argument to be passed from the driver to
74 * #GNUNET_SCHEDULER_run_from_driver(). Contains the 74 * #GNUNET_SCHEDULER_run_from_driver(). Contains the
75 * scheduler's internal state. 75 * scheduler's internal state.
76 */ 76 */
77struct GNUNET_SCHEDULER_Handle 77struct GNUNET_SCHEDULER_Handle
78{ 78{
79 /** 79 /**
@@ -94,7 +94,7 @@ struct GNUNET_SCHEDULER_Handle
94 * Driver we used for the event loop. 94 * Driver we used for the event loop.
95 */ 95 */
96 const struct GNUNET_SCHEDULER_Driver *driver; 96 const struct GNUNET_SCHEDULER_Driver *driver;
97 97
98}; 98};
99 99
100 100
@@ -127,7 +127,7 @@ struct GNUNET_SCHEDULER_Task
127 * Handle to the scheduler's state. 127 * Handle to the scheduler's state.
128 */ 128 */
129 const struct GNUNET_SCHEDULER_Handle *sh; 129 const struct GNUNET_SCHEDULER_Handle *sh;
130 130
131 /** 131 /**
132 * Set of file descriptors this task is waiting 132 * Set of file descriptors this task is waiting
133 * for for reading. Once ready, this is updated 133 * for for reading. Once ready, this is updated
@@ -172,7 +172,7 @@ struct GNUNET_SCHEDULER_Task
172 * Size of the @e fds array. 172 * Size of the @e fds array.
173 */ 173 */
174 unsigned int fds_len; 174 unsigned int fds_len;
175 175
176 /** 176 /**
177 * Why is the task ready? Set after task is added to ready queue. 177 * Why is the task ready? Set after task is added to ready queue.
178 * Initially set to zero. All reasons that have already been 178 * Initially set to zero. All reasons that have already been
@@ -227,6 +227,14 @@ struct GNUNET_SCHEDULER_Task
227 227
228}; 228};
229 229
230/**
231 * The driver used for the event loop. Will be handed over to
232 * the scheduler in #GNUNET_SCHEDULER_run_from_driver(), peristed
233 * there in this variable for later use in functions like
234 * #GNUNET_SCHEDULER_add_select(), #add_without_sets() and
235 * #GNUNET_SCHEDULER_cancel().
236 */
237GNUNET_SCHEDULER_Driver *scheduler_driver;
230 238
231/** 239/**
232 * Head of list of tasks waiting for an event. 240 * Head of list of tasks waiting for an event.
@@ -370,11 +378,9 @@ check_priority (enum GNUNET_SCHEDULER_Priority p)
370 * @param ws write-set, set to all FDs we would like to write (updated) 378 * @param ws write-set, set to all FDs we would like to write (updated)
371 * @param timeout next timeout (updated) 379 * @param timeout next timeout (updated)
372 */ 380 */
373static void 381void getNextPendingTimeout(struct GNUNET_TIME_Relative *timeout)
374update_sets (struct GNUNET_NETWORK_FDSet *rs,
375 struct GNUNET_NETWORK_FDSet *ws,
376 struct GNUNET_TIME_Relative *timeout)
377{ 382{
383
378 struct GNUNET_SCHEDULER_Task *pos; 384 struct GNUNET_SCHEDULER_Task *pos;
379 struct GNUNET_TIME_Absolute now; 385 struct GNUNET_TIME_Absolute now;
380 struct GNUNET_TIME_Relative to; 386 struct GNUNET_TIME_Relative to;
@@ -389,6 +395,20 @@ update_sets (struct GNUNET_NETWORK_FDSet *rs,
389 if (0 != pos->reason) 395 if (0 != pos->reason)
390 *timeout = GNUNET_TIME_UNIT_ZERO; 396 *timeout = GNUNET_TIME_UNIT_ZERO;
391 } 397 }
398}
399
400static void
401update_sets (struct GNUNET_NETWORK_FDSet *rs,
402 struct GNUNET_NETWORK_FDSet *ws,
403 struct GNUNET_TIME_Relative *timeout)
404{
405 struct GNUNET_SCHEDULER_Task *pos;
406 struct GNUNET_TIME_Absolute now;
407 struct GNUNET_TIME_Relative to;
408
409 now = GNUNET_TIME_absolute_get ();
410
411 getNextPendingTimeout(timeout);
392 for (pos = pending_head; NULL != pos; pos = pos->next) 412 for (pos = pending_head; NULL != pos; pos = pos->next)
393 { 413 {
394 if (pos->timeout.abs_value_us != GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) 414 if (pos->timeout.abs_value_us != GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
@@ -593,10 +613,10 @@ dump_backtrace (struct GNUNET_SCHEDULER_Task *t)
593 613
594 for (i = 0; i < t->num_backtrace_strings; i++) 614 for (i = 0; i < t->num_backtrace_strings; i++)
595 LOG (GNUNET_ERROR_TYPE_DEBUG, 615 LOG (GNUNET_ERROR_TYPE_DEBUG,
596 "Task %p trace %u: %s\n", 616 "Task %p trace %u: %s\n",
597 t, 617 t,
598 i, 618 i,
599 t->backtrace_strings[i]); 619 t->backtrace_strings[i]);
600#endif 620#endif
601} 621}
602 622
@@ -645,7 +665,7 @@ run_ready (struct GNUNET_NETWORK_FDSet *rs,
645 DELAY_THRESHOLD.rel_value_us) 665 DELAY_THRESHOLD.rel_value_us)
646 { 666 {
647 LOG (GNUNET_ERROR_TYPE_DEBUG, 667 LOG (GNUNET_ERROR_TYPE_DEBUG,
648 "Task %p took %s to be scheduled\n", 668 "Task %p took %s to be scheduled\n",
649 pos, 669 pos,
650 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (pos->start_time), 670 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (pos->start_time),
651 GNUNET_YES)); 671 GNUNET_YES));
@@ -665,7 +685,7 @@ run_ready (struct GNUNET_NETWORK_FDSet *rs,
665 (!GNUNET_NETWORK_fdset_test_native (ws, pos->write_fd))) 685 (!GNUNET_NETWORK_fdset_test_native (ws, pos->write_fd)))
666 GNUNET_assert (0); // added to ready in previous select loop! 686 GNUNET_assert (0); // added to ready in previous select loop!
667 LOG (GNUNET_ERROR_TYPE_DEBUG, 687 LOG (GNUNET_ERROR_TYPE_DEBUG,
668 "Running task: %p\n", 688 "Running task: %p\n",
669 pos); 689 pos);
670 pos->callback (pos->callback_cls); 690 pos->callback (pos->callback_cls);
671 dump_backtrace (pos); 691 dump_backtrace (pos);
@@ -769,88 +789,22 @@ check_lifeness ()
769} 789}
770 790
771 791
772/** 792
773 * Initialize and run scheduler. This function will return when all 793void while_live(struct GNUNET_NETWORK_FDSet *rs, struct GNUNET_NETWORK_FDSet *ws)
774 * tasks have completed. On systems with signals, receiving a SIGTERM
775 * (and other similar signals) will cause #GNUNET_SCHEDULER_shutdown()
776 * to be run after the active task is complete. As a result, SIGTERM
777 * causes all active tasks to be scheduled with reason
778 * #GNUNET_SCHEDULER_REASON_SHUTDOWN. (However, tasks added
779 * afterwards will execute normally!). Note that any particular signal
780 * will only shut down one scheduler; applications should always only
781 * create a single scheduler.
782 *
783 * @param task task to run immediately
784 * @param task_cls closure of @a task
785 */
786void
787GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task,
788 void *task_cls)
789{ 794{
790 struct GNUNET_NETWORK_FDSet *rs;
791 struct GNUNET_NETWORK_FDSet *ws;
792 struct GNUNET_TIME_Relative timeout;
793 int ret; 795 int ret;
794 struct GNUNET_SIGNAL_Context *shc_int;
795 struct GNUNET_SIGNAL_Context *shc_term;
796#if (SIGTERM != GNUNET_TERM_SIG)
797 struct GNUNET_SIGNAL_Context *shc_gterm;
798#endif
799
800#ifndef MINGW
801 struct GNUNET_SIGNAL_Context *shc_quit;
802 struct GNUNET_SIGNAL_Context *shc_hup;
803 struct GNUNET_SIGNAL_Context *shc_pipe;
804#endif
805 unsigned long long last_tr;
806 unsigned int busy_wait_warning; 796 unsigned int busy_wait_warning;
797 unsigned long long last_tr;
807 const struct GNUNET_DISK_FileHandle *pr; 798 const struct GNUNET_DISK_FileHandle *pr;
808 char c; 799 char c;
800 struct GNUNET_TIME_Relative timeout;
809 801
810 GNUNET_assert (NULL == active_task); 802 busy_wait_warning = 0;
811 rs = GNUNET_NETWORK_fdset_create ();
812 ws = GNUNET_NETWORK_fdset_create ();
813 GNUNET_assert (NULL == shutdown_pipe_handle);
814 shutdown_pipe_handle = GNUNET_DISK_pipe (GNUNET_NO,
815 GNUNET_NO,
816 GNUNET_NO,
817 GNUNET_NO);
818 GNUNET_assert (NULL != shutdown_pipe_handle);
819 pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle, 803 pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle,
820 GNUNET_DISK_PIPE_END_READ); 804 GNUNET_DISK_PIPE_END_READ);
821 GNUNET_assert (NULL != pr); 805 GNUNET_assert (NULL != pr);
822 my_pid = getpid ();
823 LOG (GNUNET_ERROR_TYPE_DEBUG,
824 "Registering signal handlers\n");
825 shc_int = GNUNET_SIGNAL_handler_install (SIGINT,
826 &sighandler_shutdown);
827 shc_term = GNUNET_SIGNAL_handler_install (SIGTERM,
828 &sighandler_shutdown);
829#if (SIGTERM != GNUNET_TERM_SIG)
830 shc_gterm = GNUNET_SIGNAL_handler_install (GNUNET_TERM_SIG,
831 &sighandler_shutdown);
832#endif
833#ifndef MINGW
834 shc_pipe = GNUNET_SIGNAL_handler_install (SIGPIPE,
835 &sighandler_pipe);
836 shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT,
837 &sighandler_shutdown);
838 shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP,
839 &sighandler_shutdown);
840#endif
841 current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT;
842 current_lifeness = GNUNET_YES;
843 GNUNET_SCHEDULER_add_with_reason_and_priority (task,
844 task_cls,
845 GNUNET_SCHEDULER_REASON_STARTUP,
846 GNUNET_SCHEDULER_PRIORITY_DEFAULT);
847 active_task = (void *) (long) -1; /* force passing of sanity check */
848 GNUNET_SCHEDULER_add_now_with_lifeness (GNUNET_NO,
849 &GNUNET_OS_install_parent_control_handler,
850 NULL);
851 active_task = NULL;
852 last_tr = 0; 806 last_tr = 0;
853 busy_wait_warning = 0; 807
854 while (GNUNET_OK == check_lifeness ()) 808 while (GNUNET_OK == check_lifeness ())
855 { 809 {
856 GNUNET_NETWORK_fdset_zero (rs); 810 GNUNET_NETWORK_fdset_zero (rs);
@@ -905,7 +859,7 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task,
905 LOG (GNUNET_ERROR_TYPE_ERROR, 859 LOG (GNUNET_ERROR_TYPE_ERROR,
906 "Got invalid file descriptor %d!\n", 860 "Got invalid file descriptor %d!\n",
907 t->read_fd); 861 t->read_fd);
908 dump_backtrace (t); 862 dump_backtrace (t);
909 } 863 }
910 } 864 }
911 if (-1 != t->write_fd) 865 if (-1 != t->write_fd)
@@ -916,7 +870,7 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task,
916 LOG (GNUNET_ERROR_TYPE_ERROR, 870 LOG (GNUNET_ERROR_TYPE_ERROR,
917 "Got invalid file descriptor %d!\n", 871 "Got invalid file descriptor %d!\n",
918 t->write_fd); 872 t->write_fd);
919 dump_backtrace (t); 873 dump_backtrace (t);
920 } 874 }
921 } 875 }
922 } 876 }
@@ -953,6 +907,89 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task,
953 busy_wait_warning = 0; 907 busy_wait_warning = 0;
954 } 908 }
955 } 909 }
910}
911
912/**
913 * Initialize and run scheduler. This function will return when all
914 * tasks have completed. On systems with signals, receiving a SIGTERM
915 * (and other similar signals) will cause #GNUNET_SCHEDULER_shutdown()
916 * to be run after the active task is complete. As a result, SIGTERM
917 * causes all active tasks to be scheduled with reason
918 * #GNUNET_SCHEDULER_REASON_SHUTDOWN. (However, tasks added
919 * afterwards will execute normally!). Note that any particular signal
920 * will only shut down one scheduler; applications should always only
921 * create a single scheduler.
922 *
923 * @param task task to run immediately
924 * @param task_cls closure of @a task
925 */
926void
927GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task,
928 void *task_cls)
929{
930 struct GNUNET_NETWORK_FDSet *rs;
931 struct GNUNET_NETWORK_FDSet *ws;
932
933
934 struct GNUNET_SIGNAL_Context *shc_int;
935 struct GNUNET_SIGNAL_Context *shc_term;
936#if (SIGTERM != GNUNET_TERM_SIG)
937 struct GNUNET_SIGNAL_Context *shc_gterm;
938#endif
939
940#ifndef MINGW
941 struct GNUNET_SIGNAL_Context *shc_quit;
942 struct GNUNET_SIGNAL_Context *shc_hup;
943 struct GNUNET_SIGNAL_Context *shc_pipe;
944#endif
945
946 unsigned int busy_wait_warning;
947
948
949
950 GNUNET_assert (NULL == active_task);
951 rs = GNUNET_NETWORK_fdset_create ();
952 ws = GNUNET_NETWORK_fdset_create ();
953 GNUNET_assert (NULL == shutdown_pipe_handle);
954 shutdown_pipe_handle = GNUNET_DISK_pipe (GNUNET_NO,
955 GNUNET_NO,
956 GNUNET_NO,
957 GNUNET_NO);
958 GNUNET_assert (NULL != shutdown_pipe_handle);
959
960 my_pid = getpid ();
961 LOG (GNUNET_ERROR_TYPE_DEBUG,
962 "Registering signal handlers\n");
963 shc_int = GNUNET_SIGNAL_handler_install (SIGINT,
964 &sighandler_shutdown);
965 shc_term = GNUNET_SIGNAL_handler_install (SIGTERM,
966 &sighandler_shutdown);
967#if (SIGTERM != GNUNET_TERM_SIG)
968 shc_gterm = GNUNET_SIGNAL_handler_install (GNUNET_TERM_SIG,
969 &sighandler_shutdown);
970#endif
971#ifndef MINGW
972 shc_pipe = GNUNET_SIGNAL_handler_install (SIGPIPE,
973 &sighandler_pipe);
974 shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT,
975 &sighandler_shutdown);
976 shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP,
977 &sighandler_shutdown);
978#endif
979 current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT;
980 current_lifeness = GNUNET_YES;
981 GNUNET_SCHEDULER_add_with_reason_and_priority (task,
982 task_cls,
983 GNUNET_SCHEDULER_REASON_STARTUP,
984 GNUNET_SCHEDULER_PRIORITY_DEFAULT);
985 active_task = (void *) (long) -1; /* force passing of sanity check */
986 GNUNET_SCHEDULER_add_now_with_lifeness (GNUNET_NO,
987 &GNUNET_OS_install_parent_control_handler,
988 NULL);
989 active_task = NULL;
990
991
992 while_live(rs, ws);
956 GNUNET_SIGNAL_handler_uninstall (shc_int); 993 GNUNET_SIGNAL_handler_uninstall (shc_int);
957 GNUNET_SIGNAL_handler_uninstall (shc_term); 994 GNUNET_SIGNAL_handler_uninstall (shc_term);
958#if (SIGTERM != GNUNET_TERM_SIG) 995#if (SIGTERM != GNUNET_TERM_SIG)
@@ -1018,14 +1055,29 @@ GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p)
1018 * @param task id of the task to cancel 1055 * @param task id of the task to cancel
1019 * @return original closure of the task 1056 * @return original closure of the task
1020 */ 1057 */
1058void initFdINfo(GNUNET_SCHEDULER_FdInfo *fdi, struct GNUNET_SCHEDULER_Task *task)
1059{
1060 if (-1 != task->read_fd)
1061 {
1062 fdi->sock=task->read_fd;
1063 }else if (-1 != task->write_fd){
1064 fdi->sock=task->write_fd;
1065 } else if (NULL != task->read_set){
1066 fdi->fd=task->read_set;
1067 }else if (NULL != task->write_set){
1068 fdi->fd=task->write_set;
1069 }
1070}
1071
1021void * 1072void *
1022GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task) 1073GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task)
1023{ 1074{
1024 enum GNUNET_SCHEDULER_Priority p; 1075 enum GNUNET_SCHEDULER_Priority p;
1025 void *ret; 1076 void *ret;
1077 GNUNET_SCHEDULER_FdInfo *fdi;
1026 1078
1027 GNUNET_assert ( (NULL != active_task) || 1079 GNUNET_assert ( (NULL != active_task) ||
1028 (GNUNET_NO == task->lifeness) ); 1080 (GNUNET_NO == task->lifeness) );
1029 if (! task->in_ready_list) 1081 if (! task->in_ready_list)
1030 { 1082 {
1031 if ( (-1 == task->read_fd) && 1083 if ( (-1 == task->read_fd) &&
@@ -1034,21 +1086,24 @@ GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task)
1034 (NULL == task->write_set) ) 1086 (NULL == task->write_set) )
1035 { 1087 {
1036 if (GNUNET_YES == task->on_shutdown) 1088 if (GNUNET_YES == task->on_shutdown)
1037 GNUNET_CONTAINER_DLL_remove (shutdown_head, 1089 GNUNET_CONTAINER_DLL_remove (shutdown_head,
1038 shutdown_tail, 1090 shutdown_tail,
1039 task); 1091 task);
1040 else 1092 else
1041 GNUNET_CONTAINER_DLL_remove (pending_timeout_head, 1093 GNUNET_CONTAINER_DLL_remove (pending_timeout_head,
1042 pending_timeout_tail, 1094 pending_timeout_tail,
1043 task); 1095 task);
1044 if (task == pending_timeout_last) 1096 if (task == pending_timeout_last)
1045 pending_timeout_last = NULL; 1097 pending_timeout_last = NULL;
1046 } 1098 }
1047 else 1099 else
1048 { 1100 {
1049 GNUNET_CONTAINER_DLL_remove (pending_head, 1101 /*GNUNET_CONTAINER_DLL_remove (pending_head,
1050 pending_tail, 1102 pending_tail,
1051 task); 1103 task);*/
1104 fdi = GNUNET_new (struct GNUNET_SCHEDULER_FdInfo);
1105 initFdINfo(fdi, task);
1106 scheduler_driver->del(scheduler_driver->cls, task, fdi);
1052 } 1107 }
1053 } 1108 }
1054 else 1109 else
@@ -1083,7 +1138,7 @@ init_backtrace (struct GNUNET_SCHEDULER_Task *t)
1083 = backtrace (backtrace_array, MAX_TRACE_DEPTH); 1138 = backtrace (backtrace_array, MAX_TRACE_DEPTH);
1084 t->backtrace_strings = 1139 t->backtrace_strings =
1085 backtrace_symbols (backtrace_array, 1140 backtrace_symbols (backtrace_array,
1086 t->num_backtrace_strings); 1141 t->num_backtrace_strings);
1087 dump_backtrace (t); 1142 dump_backtrace (t);
1088#endif 1143#endif
1089} 1144}
@@ -1220,8 +1275,8 @@ GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at,
1220 */ 1275 */
1221struct GNUNET_SCHEDULER_Task * 1276struct GNUNET_SCHEDULER_Task *
1222GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay, 1277GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay,
1223 enum GNUNET_SCHEDULER_Priority priority, 1278 enum GNUNET_SCHEDULER_Priority priority,
1224 GNUNET_SCHEDULER_TaskCallback task, 1279 GNUNET_SCHEDULER_TaskCallback task,
1225 void *task_cls) 1280 void *task_cls)
1226{ 1281{
1227 return GNUNET_SCHEDULER_add_at_with_priority (GNUNET_TIME_relative_to_absolute (delay), 1282 return GNUNET_SCHEDULER_add_at_with_priority (GNUNET_TIME_relative_to_absolute (delay),
@@ -1289,11 +1344,11 @@ GNUNET_SCHEDULER_add_at (struct GNUNET_TIME_Absolute at,
1289struct GNUNET_SCHEDULER_Task * 1344struct GNUNET_SCHEDULER_Task *
1290GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay, 1345GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
1291 GNUNET_SCHEDULER_TaskCallback task, 1346 GNUNET_SCHEDULER_TaskCallback task,
1292 void *task_cls) 1347 void *task_cls)
1293{ 1348{
1294 return GNUNET_SCHEDULER_add_delayed_with_priority (delay, 1349 return GNUNET_SCHEDULER_add_delayed_with_priority (delay,
1295 GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1350 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1296 task, 1351 task,
1297 task_cls); 1352 task_cls);
1298} 1353}
1299 1354
@@ -1315,11 +1370,11 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
1315 */ 1370 */
1316struct GNUNET_SCHEDULER_Task * 1371struct GNUNET_SCHEDULER_Task *
1317GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_TaskCallback task, 1372GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_TaskCallback task,
1318 void *task_cls) 1373 void *task_cls)
1319{ 1374{
1320 return GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_ZERO, 1375 return GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_ZERO,
1321 task, 1376 task,
1322 task_cls); 1377 task_cls);
1323} 1378}
1324 1379
1325 1380
@@ -1335,7 +1390,7 @@ GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_TaskCallback task,
1335 */ 1390 */
1336struct GNUNET_SCHEDULER_Task * 1391struct GNUNET_SCHEDULER_Task *
1337GNUNET_SCHEDULER_add_shutdown (GNUNET_SCHEDULER_TaskCallback task, 1392GNUNET_SCHEDULER_add_shutdown (GNUNET_SCHEDULER_TaskCallback task,
1338 void *task_cls) 1393 void *task_cls)
1339{ 1394{
1340 struct GNUNET_SCHEDULER_Task *t; 1395 struct GNUNET_SCHEDULER_Task *t;
1341 1396
@@ -1354,8 +1409,8 @@ GNUNET_SCHEDULER_add_shutdown (GNUNET_SCHEDULER_TaskCallback task,
1354 t->on_shutdown = GNUNET_YES; 1409 t->on_shutdown = GNUNET_YES;
1355 t->lifeness = GNUNET_YES; 1410 t->lifeness = GNUNET_YES;
1356 GNUNET_CONTAINER_DLL_insert (shutdown_head, 1411 GNUNET_CONTAINER_DLL_insert (shutdown_head,
1357 shutdown_tail, 1412 shutdown_tail,
1358 t); 1413 t);
1359 LOG (GNUNET_ERROR_TYPE_DEBUG, 1414 LOG (GNUNET_ERROR_TYPE_DEBUG,
1360 "Adding task: %p\n", 1415 "Adding task: %p\n",
1361 t); 1416 t);
@@ -1419,8 +1474,8 @@ GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness,
1419#ifndef MINGW 1474#ifndef MINGW
1420static struct GNUNET_SCHEDULER_Task * 1475static struct GNUNET_SCHEDULER_Task *
1421add_without_sets (struct GNUNET_TIME_Relative delay, 1476add_without_sets (struct GNUNET_TIME_Relative delay,
1422 enum GNUNET_SCHEDULER_Priority priority, 1477 enum GNUNET_SCHEDULER_Priority priority,
1423 int rfd, 1478 int rfd,
1424 int wfd, 1479 int wfd,
1425 GNUNET_SCHEDULER_TaskCallback task, 1480 GNUNET_SCHEDULER_TaskCallback task,
1426 void *task_cls) 1481 void *task_cls)
@@ -1469,9 +1524,12 @@ add_without_sets (struct GNUNET_TIME_Relative delay,
1469 t->timeout = GNUNET_TIME_relative_to_absolute (delay); 1524 t->timeout = GNUNET_TIME_relative_to_absolute (delay);
1470 t->priority = check_priority ((priority == GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : priority); 1525 t->priority = check_priority ((priority == GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : priority);
1471 t->lifeness = current_lifeness; 1526 t->lifeness = current_lifeness;
1472 GNUNET_CONTAINER_DLL_insert (pending_head, 1527 /*GNUNET_CONTAINER_DLL_insert (pending_head,
1473 pending_tail, 1528 pending_tail,
1474 t); 1529 t);*/
1530 fdi = GNUNET_new (struct GNUNET_SCHEDULER_FdInfo);
1531 initFdINfo(fdi, task);
1532 scheduler_driver->add(scheduler_driver, t , fdi);
1475 max_priority_added = GNUNET_MAX (max_priority_added, 1533 max_priority_added = GNUNET_MAX (max_priority_added,
1476 t->priority); 1534 t->priority);
1477 LOG (GNUNET_ERROR_TYPE_DEBUG, 1535 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -1504,8 +1562,8 @@ GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
1504 void *task_cls) 1562 void *task_cls)
1505{ 1563{
1506 return GNUNET_SCHEDULER_add_read_net_with_priority (delay, 1564 return GNUNET_SCHEDULER_add_read_net_with_priority (delay,
1507 GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1565 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1508 rfd, task, task_cls); 1566 rfd, task, task_cls);
1509} 1567}
1510 1568
1511 1569
@@ -1527,9 +1585,9 @@ GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay,
1527 */ 1585 */
1528struct GNUNET_SCHEDULER_Task * 1586struct GNUNET_SCHEDULER_Task *
1529GNUNET_SCHEDULER_add_read_net_with_priority (struct GNUNET_TIME_Relative delay, 1587GNUNET_SCHEDULER_add_read_net_with_priority (struct GNUNET_TIME_Relative delay,
1530 enum GNUNET_SCHEDULER_Priority priority, 1588 enum GNUNET_SCHEDULER_Priority priority,
1531 struct GNUNET_NETWORK_Handle *rfd, 1589 struct GNUNET_NETWORK_Handle *rfd,
1532 GNUNET_SCHEDULER_TaskCallback task, 1590 GNUNET_SCHEDULER_TaskCallback task,
1533 void *task_cls) 1591 void *task_cls)
1534{ 1592{
1535 return GNUNET_SCHEDULER_add_net_with_priority (delay, priority, 1593 return GNUNET_SCHEDULER_add_net_with_priority (delay, priority,
@@ -1789,11 +1847,14 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
1789 GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : 1847 GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority :
1790 prio); 1848 prio);
1791 t->lifeness = current_lifeness; 1849 t->lifeness = current_lifeness;
1792 GNUNET_CONTAINER_DLL_insert (pending_head, 1850 /*GNUNET_CONTAINER_DLL_insert (pending_head,
1793 pending_tail, 1851 pending_tail,
1794 t); 1852 t);*/
1853 fdi = GNUNET_new (struct GNUNET_SCHEDULER_FdInfo);
1854 initFdINfo(fdi, task);
1855 scheduler_driver->add(scheduler_driver, t , fdi);
1795 max_priority_added = GNUNET_MAX (max_priority_added, 1856 max_priority_added = GNUNET_MAX (max_priority_added,
1796 t->priority); 1857 t->priority);
1797 LOG (GNUNET_ERROR_TYPE_DEBUG, 1858 LOG (GNUNET_ERROR_TYPE_DEBUG,
1798 "Adding task %p\n", 1859 "Adding task %p\n",
1799 t); 1860 t);
@@ -1814,7 +1875,7 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
1814 */ 1875 */
1815void 1876void
1816GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task, 1877GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task,
1817 enum GNUNET_SCHEDULER_EventType et) 1878 enum GNUNET_SCHEDULER_EventType et)
1818{ 1879{
1819 enum GNUNET_SCHEDULER_Reason reason; 1880 enum GNUNET_SCHEDULER_Reason reason;
1820 struct GNUNET_TIME_Absolute now; 1881 struct GNUNET_TIME_Absolute now;
@@ -1849,7 +1910,7 @@ GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task,
1849 * 1910 *
1850 * @param sh scheduler handle that was given to the `loop` 1911 * @param sh scheduler handle that was given to the `loop`
1851 * @return #GNUNET_OK if there are more tasks that are ready, 1912 * @return #GNUNET_OK if there are more tasks that are ready,
1852 * and thus we would like to run more (yield to avoid 1913 * and thus we would like to run more (yield to avoid
1853 * blocking other activities for too long) 1914 * blocking other activities for too long)
1854 * #GNUNET_NO if we are done running tasks (yield to block) 1915 * #GNUNET_NO if we are done running tasks (yield to block)
1855 * #GNUNET_SYSERR on error 1916 * #GNUNET_SYSERR on error
@@ -1876,11 +1937,11 @@ GNUNET_SCHEDULER_run_from_driver (struct GNUNET_SCHEDULER_Handle *sh)
1876 pending_timeout_last = NULL; 1937 pending_timeout_last = NULL;
1877 queue_ready_task (pos); 1938 queue_ready_task (pos);
1878 } 1939 }
1879 1940
1880 if (0 == ready_count) 1941 if (0 == ready_count)
1881 return GNUNET_NO; 1942 return GNUNET_NO;
1882 1943
1883 /* find out which task priority level we are going to 1944 /* find out which task priority level we are going to
1884 process this time */ 1945 process this time */
1885 max_priority_added = GNUNET_SCHEDULER_PRIORITY_KEEP; 1946 max_priority_added = GNUNET_SCHEDULER_PRIORITY_KEEP;
1886 GNUNET_assert (NULL == ready_head[GNUNET_SCHEDULER_PRIORITY_KEEP]); 1947 GNUNET_assert (NULL == ready_head[GNUNET_SCHEDULER_PRIORITY_KEEP]);
@@ -1898,21 +1959,21 @@ GNUNET_SCHEDULER_run_from_driver (struct GNUNET_SCHEDULER_Handle *sh)
1898 while (NULL != (pos = ready_head[p])) 1959 while (NULL != (pos = ready_head[p]))
1899 { 1960 {
1900 GNUNET_CONTAINER_DLL_remove (ready_head[p], 1961 GNUNET_CONTAINER_DLL_remove (ready_head[p],
1901 ready_tail[p], 1962 ready_tail[p],
1902 pos); 1963 pos);
1903 ready_count--; 1964 ready_count--;
1904 current_priority = pos->priority; 1965 current_priority = pos->priority;
1905 current_lifeness = pos->lifeness; 1966 current_lifeness = pos->lifeness;
1906 active_task = pos; 1967 active_task = pos;
1907#if PROFILE_DELAYS 1968#if PROFILE_DELAYS
1908 if (GNUNET_TIME_absolute_get_duration (pos->start_time).rel_value_us > 1969 if (GNUNET_TIME_absolute_get_duration (pos->start_time).rel_value_us >
1909 DELAY_THRESHOLD.rel_value_us) 1970 DELAY_THRESHOLD.rel_value_us)
1910 { 1971 {
1911 LOG (GNUNET_ERROR_TYPE_DEBUG, 1972 LOG (GNUNET_ERROR_TYPE_DEBUG,
1912 "Task %p took %s to be scheduled\n", 1973 "Task %p took %s to be scheduled\n",
1913 pos, 1974 pos,
1914 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (pos->start_time), 1975 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (pos->start_time),
1915 GNUNET_YES)); 1976 GNUNET_YES));
1916 } 1977 }
1917#endif 1978#endif
1918 tc.reason = pos->reason; 1979 tc.reason = pos->reason;
@@ -1922,17 +1983,17 @@ GNUNET_SCHEDULER_run_from_driver (struct GNUNET_SCHEDULER_Handle *sh)
1922 tc.fds = pos->fds; 1983 tc.fds = pos->fds;
1923 tc.read_ready = (NULL == pos->read_set) ? sh->rs : pos->read_set; 1984 tc.read_ready = (NULL == pos->read_set) ? sh->rs : pos->read_set;
1924 if ( (-1 != pos->read_fd) && 1985 if ( (-1 != pos->read_fd) &&
1925 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_READ_READY)) ) 1986 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_READ_READY)) )
1926 GNUNET_NETWORK_fdset_set_native (sh->rs, 1987 GNUNET_NETWORK_fdset_set_native (sh->rs,
1927 pos->read_fd); 1988 pos->read_fd);
1928 tc.write_ready = (NULL == pos->write_set) ? sh->ws : pos->write_set; 1989 tc.write_ready = (NULL == pos->write_set) ? sh->ws : pos->write_set;
1929 if ((-1 != pos->write_fd) && 1990 if ((-1 != pos->write_fd) &&
1930 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_WRITE_READY))) 1991 (0 != (pos->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)))
1931 GNUNET_NETWORK_fdset_set_native (sh->ws, 1992 GNUNET_NETWORK_fdset_set_native (sh->ws,
1932 pos->write_fd); 1993 pos->write_fd);
1933 LOG (GNUNET_ERROR_TYPE_DEBUG, 1994 LOG (GNUNET_ERROR_TYPE_DEBUG,
1934 "Running task: %p\n", 1995 "Running task: %p\n",
1935 pos); 1996 pos);
1936 pos->callback (pos->callback_cls); 1997 pos->callback (pos->callback_cls);
1937 active_task = NULL; 1998 active_task = NULL;
1938 dump_backtrace (pos); 1999 dump_backtrace (pos);
@@ -1963,8 +2024,8 @@ GNUNET_SCHEDULER_run_from_driver (struct GNUNET_SCHEDULER_Handle *sh)
1963 */ 2024 */
1964int 2025int
1965GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver, 2026GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver,
1966 GNUNET_SCHEDULER_TaskCallback task, 2027 GNUNET_SCHEDULER_TaskCallback task,
1967 void *task_cls) 2028 void *task_cls)
1968{ 2029{
1969 int ret; 2030 int ret;
1970 struct GNUNET_SIGNAL_Context *shc_int; 2031 struct GNUNET_SIGNAL_Context *shc_int;
@@ -1979,7 +2040,7 @@ GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver,
1979#endif 2040#endif
1980 struct GNUNET_SCHEDULER_Task tsk; 2041 struct GNUNET_SCHEDULER_Task tsk;
1981 const struct GNUNET_DISK_FileHandle *pr; 2042 const struct GNUNET_DISK_FileHandle *pr;
1982 struct GNUNET_SCHEDULER_Handle sh; 2043 scheduler_driver = driver;
1983 2044
1984 /* general set-up */ 2045 /* general set-up */
1985 GNUNET_assert (NULL == active_task); 2046 GNUNET_assert (NULL == active_task);
@@ -1998,28 +2059,28 @@ GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver,
1998 LOG (GNUNET_ERROR_TYPE_DEBUG, 2059 LOG (GNUNET_ERROR_TYPE_DEBUG,
1999 "Registering signal handlers\n"); 2060 "Registering signal handlers\n");
2000 shc_int = GNUNET_SIGNAL_handler_install (SIGINT, 2061 shc_int = GNUNET_SIGNAL_handler_install (SIGINT,
2001 &sighandler_shutdown); 2062 &sighandler_shutdown);
2002 shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, 2063 shc_term = GNUNET_SIGNAL_handler_install (SIGTERM,
2003 &sighandler_shutdown); 2064 &sighandler_shutdown);
2004#if (SIGTERM != GNUNET_TERM_SIG) 2065#if (SIGTERM != GNUNET_TERM_SIG)
2005 shc_gterm = GNUNET_SIGNAL_handler_install (GNUNET_TERM_SIG, 2066 shc_gterm = GNUNET_SIGNAL_handler_install (GNUNET_TERM_SIG,
2006 &sighandler_shutdown); 2067 &sighandler_shutdown);
2007#endif 2068#endif
2008#ifndef MINGW 2069#ifndef MINGW
2009 shc_pipe = GNUNET_SIGNAL_handler_install (SIGPIPE, 2070 shc_pipe = GNUNET_SIGNAL_handler_install (SIGPIPE,
2010 &sighandler_pipe); 2071 &sighandler_pipe);
2011 shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT, 2072 shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT,
2012 &sighandler_shutdown); 2073 &sighandler_shutdown);
2013 shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP, 2074 shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP,
2014 &sighandler_shutdown); 2075 &sighandler_shutdown);
2015#endif 2076#endif
2016 2077
2017 /* Setup initial tasks */ 2078 /* Setup initial tasks */
2018 current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT; 2079 current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT;
2019 current_lifeness = GNUNET_YES; 2080 current_lifeness = GNUNET_YES;
2020 memset (&tsk, 2081 memset (&tsk,
2021 0, 2082 0,
2022 sizeof (tsk)); 2083 sizeof (tsk));
2023 active_task = &tsk; 2084 active_task = &tsk;
2024 tsk.sh = &sh; 2085 tsk.sh = &sh;
2025 GNUNET_SCHEDULER_add_with_reason_and_priority (task, 2086 GNUNET_SCHEDULER_add_with_reason_and_priority (task,
@@ -2031,14 +2092,15 @@ GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver,
2031 NULL); 2092 NULL);
2032 active_task = NULL; 2093 active_task = NULL;
2033 driver->set_wakeup (driver->cls, 2094 driver->set_wakeup (driver->cls,
2034 GNUNET_TIME_absolute_get ()); 2095 GNUNET_TIME_absolute_get ());
2035 2096
2036 /* begin main event loop */ 2097 /* begin main event loop */
2037 sh.rs = GNUNET_NETWORK_fdset_create (); 2098 sh.rs = GNUNET_NETWORK_fdset_create ();
2038 sh.ws = GNUNET_NETWORK_fdset_create (); 2099 sh.ws = GNUNET_NETWORK_fdset_create ();
2100 GNUNET_NETWORK_fdset_handle_set (rs, pr);
2039 sh.driver = driver; 2101 sh.driver = driver;
2040 ret = driver->loop (driver->cls, 2102 ret = driver->loop (driver->cls,
2041 &sh); 2103 &sh);
2042 GNUNET_NETWORK_fdset_destroy (sh.rs); 2104 GNUNET_NETWORK_fdset_destroy (sh.rs);
2043 GNUNET_NETWORK_fdset_destroy (sh.ws); 2105 GNUNET_NETWORK_fdset_destroy (sh.ws);
2044 2106
@@ -2058,6 +2120,45 @@ GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver,
2058 return ret; 2120 return ret;
2059} 2121}
2060 2122
2123int
2124select_add(void *cls,
2125 struct GNUNET_SCHEDULER_Task *task,
2126 struct GNUNET_SCHEDULER_FdInfo *fdi){
2127
2128 GNUNET_CONTAINER_DLL_insert (pending_head,
2129 pending_tail,
2130 task);
2131
2132}
2133
2134int
2135select_del(void *cls,
2136 struct GNUNET_SCHEDULER_Task *task,
2137 struct GNUNET_SCHEDULER_FdInfo *fdi){
2138
2139 GNUNET_CONTAINER_DLL_remove (pending_head,
2140 pending_tail,
2141 task);
2142
2143}
2144
2145
2146int
2147select_loop(void *cls,
2148 struct GNUNET_SCHEDULER_Handle *sh){
2149
2150 while_live(sh-rs, sh->ws);
2151
2152}
2153
2154void
2155select_set_wakeup(void *cls,
2156 struct GNUNET_TIME_Absolute dt){
2157
2158
2159
2160}
2161
2061 2162
2062/** 2163/**
2063 * Obtain the driver for using select() as the event loop. 2164 * Obtain the driver for using select() as the event loop.
@@ -2067,8 +2168,18 @@ GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver,
2067const struct GNUNET_SCHEDULER_Driver * 2168const struct GNUNET_SCHEDULER_Driver *
2068GNUNET_SCHEDULER_driver_select () 2169GNUNET_SCHEDULER_driver_select ()
2069{ 2170{
2070 GNUNET_break (0); // not implemented 2171
2071 return NULL; 2172 GNUNET_SCHEDULER_Driver *select_driver;
2173
2174 select_driver = GNUNET_new (struct GNUNET_SCHEDULER_Driver);
2175
2176 select_driver->loop = &select_loop;
2177 select_driver->add = &select_add;
2178 select_driver->del = &select_del;
2179 select_driver->set_wakeup = &select_set_wakeup;
2180
2181
2182 return select_driver;
2072} 2183}
2073 2184
2074 2185