diff options
author | t3sserakt <t3ss@posteo.de> | 2017-08-02 22:55:04 +0200 |
---|---|---|
committer | t3sserakt <t3ss@posteo.de> | 2017-08-02 22:55:04 +0200 |
commit | d3cd9042bf5ba56e4577507842d6f66c8ba4b3c4 (patch) | |
tree | 0cd6cd0a02ac6b447c7bb4fc08e6ba107afd0a21 /src/util/scheduler.c | |
parent | 516babaed25b7b23ba27fc837bdc19643ec54d78 (diff) | |
download | gnunet-d3cd9042bf5ba56e4577507842d6f66c8ba4b3c4.tar.gz gnunet-d3cd9042bf5ba56e4577507842d6f66c8ba4b3c4.zip |
Nearly finished. Call to set_wakeup missing in case of tasks added to pending_timeout
Diffstat (limited to 'src/util/scheduler.c')
-rw-r--r-- | src/util/scheduler.c | 158 |
1 files changed, 73 insertions, 85 deletions
diff --git a/src/util/scheduler.c b/src/util/scheduler.c index 070c0daa8..9061200bd 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c | |||
@@ -234,7 +234,7 @@ struct GNUNET_SCHEDULER_Task | |||
234 | * #GNUNET_SCHEDULER_add_select(), #add_without_sets() and | 234 | * #GNUNET_SCHEDULER_add_select(), #add_without_sets() and |
235 | * #GNUNET_SCHEDULER_cancel(). | 235 | * #GNUNET_SCHEDULER_cancel(). |
236 | */ | 236 | */ |
237 | static struct GNUNET_SCHEDULER_Driver *scheduler_driver; | 237 | static const struct GNUNET_SCHEDULER_Driver *scheduler_driver; |
238 | 238 | ||
239 | /** | 239 | /** |
240 | * Head of list of tasks waiting for an event. | 240 | * Head of list of tasks waiting for an event. |
@@ -943,8 +943,6 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, | |||
943 | struct GNUNET_SIGNAL_Context *shc_pipe; | 943 | struct GNUNET_SIGNAL_Context *shc_pipe; |
944 | #endif | 944 | #endif |
945 | 945 | ||
946 | unsigned int busy_wait_warning; | ||
947 | |||
948 | 946 | ||
949 | 947 | ||
950 | GNUNET_assert (NULL == active_task); | 948 | GNUNET_assert (NULL == active_task); |
@@ -1047,84 +1045,74 @@ GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p) | |||
1047 | return ret; | 1045 | return ret; |
1048 | } | 1046 | } |
1049 | 1047 | ||
1050 | 1048 | static struct GNUNET_SCHEDULER_Task* | |
1051 | /** | 1049 | initFdInfo(const struct GNUNET_NETWORK_Handle *read_nh, |
1052 | * Cancel the task with the specified identifier. | 1050 | const struct GNUNET_NETWORK_Handle *write_nh, |
1053 | * The task must not yet have run. | 1051 | const struct GNUNET_DISK_FileHandle *read_fh, |
1054 | * | 1052 | const struct GNUNET_DISK_FileHandle *write_fh) |
1055 | * @param task id of the task to cancel | ||
1056 | * @return original closure of the task | ||
1057 | */ | ||
1058 | void | ||
1059 | initFdInfo(struct GNUNET_SCHEDULER_Task *task, | ||
1060 | struct GNUNET_NETWORK_Handle *read_nh, | ||
1061 | struct GNUNET_NETWORK_Handle *write_nh, | ||
1062 | struct GNUNET_DISK_FileHandle *read_fh, | ||
1063 | struct GNUNET_DISK_FileHandle *write_fh) | ||
1064 | { | 1053 | { |
1054 | |||
1055 | |||
1056 | struct GNUNET_SCHEDULER_Task *t; | ||
1057 | |||
1058 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); | ||
1059 | |||
1065 | // either only network handles or only file handles are allowed | 1060 | // either only network handles or only file handles are allowed |
1066 | GNUNET_assert (!((NULL != read_nh || NULL != write_nh) && (NULL != read_fh || NULL != write_fh))); | 1061 | GNUNET_assert (!((NULL != read_nh || NULL != write_nh) && (NULL != read_fh || NULL != write_fh))); |
1067 | 1062 | ||
1068 | if (NULL != read_nh && NULL != write_nh) | 1063 | if (NULL != read_nh && NULL != write_nh) |
1069 | { | 1064 | { |
1070 | t->fds_len = 2; | 1065 | t->fds_len = 2; |
1071 | t->fds = | 1066 | t->fds = GNUNET_new_array (2, struct GNUNET_SCHEDULER_FdInfo); |
1072 | GNUNET_new_array (2, struct GNUNET_SCHEDULER_FdInfo); | 1067 | const struct GNUNET_SCHEDULER_FdInfo read_fdi = { .fd = read_nh, .et = GNUNET_SCHEDULER_ET_IN, .sock = GNUNET_NETWORK_get_fd (read_nh)}; |
1073 | struct GNUNET_SCHEDULER_FdInfo *read_fdi = t->fds; | 1068 | const struct GNUNET_SCHEDULER_FdInfo write_fdi = { .fd = write_nh, .et = GNUNET_SCHEDULER_ET_OUT, .sock = GNUNET_NETWORK_get_fd (write_nh)}; |
1074 | struct GNUENT_SCHEDULER_FdInfo *write_fdi = t->fds + 1; | 1069 | |
1075 | read_fdi->fd = read_nh; | 1070 | const struct GNUNET_SCHEDULER_FdInfo array[2] = {read_fdi, write_fdi}; |
1076 | read_fdi->et = GNUNET_SCHEDULER_ET_IN; | 1071 | t->fds = array; |
1077 | read_fdi->sock = GNUNET_NETWORK_get_fd (read_nh); | ||
1078 | write_fdi->fd = write_nh; | ||
1079 | write_fdi->et = GNUNET_SCHEDULER_ET_OUT; | ||
1080 | write_fdi->sock = GNUNET_NETWORK_get_fd (write_nh); | ||
1081 | } | 1072 | } |
1082 | else if (NULL != read_fh && NULL != write_fh) | 1073 | else if (NULL != read_fh && NULL != write_fh) |
1083 | { | 1074 | { |
1084 | t->fds_len = 2; | 1075 | t->fds_len = 2; |
1085 | t->fds = | 1076 | t->fds = GNUNET_new_array (2, struct GNUNET_SCHEDULER_FdInfo); |
1086 | GNUNET_new_array (2, struct GNUNET_SCHEDULER_FdInfo); | 1077 | const struct GNUNET_SCHEDULER_FdInfo read_fdi = { .fh = read_fh, .et = GNUNET_SCHEDULER_ET_IN}; |
1087 | struct GNUNET_SCHEDULER_FdInfo *read_fdi = t->fds; | 1078 | const struct GNUNET_SCHEDULER_FdInfo write_fdi = { .fh = write_fh, .et = GNUNET_SCHEDULER_ET_OUT, .sock = GNUNET_NETWORK_get_fd (write_nh)}; |
1088 | struct GNUENT_SCHEDULER_FdInfo *write_fdi = t->fds + 1; | 1079 | const struct GNUNET_SCHEDULER_FdInfo array[2] = {read_fdi, write_fdi}; |
1089 | read_fdi->fh = read_fh; | 1080 | t->fds = array; |
1090 | read_fdi->et = GNUNET_SCHEDULER_ET_IN; | ||
1091 | write_fdi->fh = write_fh; | ||
1092 | write_fdi->et = GNUNET_SCHEDULER_ET_OUT; | ||
1093 | } | 1081 | } |
1094 | else if (NULL != read_nh) | 1082 | else if (NULL != read_nh) |
1095 | { | 1083 | { |
1096 | struct GNUNET_SCHEDULER_FdInfo *read_fdi = &t->fdx; | 1084 | struct GNUNET_SCHEDULER_FdInfo read_fdi = { .fd = read_nh, .et = GNUNET_SCHEDULER_ET_IN, .sock = GNUNET_NETWORK_get_fd (read_nh)}; |
1097 | read_fdi->fd = read_nh; | 1085 | t->fdx = read_fdi; |
1098 | read_fdi->et = GNUNET_SCHEDULER_ET_IN; | ||
1099 | read_fdi->sock = GNUNET_NETWORK_get_fd (read_nh); | ||
1100 | } | 1086 | } |
1101 | else if (NULL != write_nh) | 1087 | else if (NULL != write_nh) |
1102 | { | 1088 | { |
1103 | struct GNUNET_SCHEDULER_FdInfo *write_fdi = &t->fdx; | 1089 | struct GNUNET_SCHEDULER_FdInfo write_fdi = { .fd = write_nh, .et = GNUNET_SCHEDULER_ET_OUT, .sock = GNUNET_NETWORK_get_fd (write_nh)}; |
1104 | write_fdi->fd = write_nh; | 1090 | t->fdx = write_fdi; |
1105 | write_fdi->et = GNUNET_SCHEDULER_ET_OUT; | ||
1106 | write_fdi->sock = GNUNET_NETWORK_get_fd (write_nh); | ||
1107 | } | 1091 | } |
1108 | else if (NULL != read_fh) | 1092 | else if (NULL != read_fh) |
1109 | { | 1093 | { |
1110 | struct GNUNET_SCHEDULER_FdInfo *read_fdi = &t->fdx; | 1094 | struct GNUNET_SCHEDULER_FdInfo read_fdi = { .fh = read_fh, .et = GNUNET_SCHEDULER_ET_IN}; |
1111 | read_fdi->fh = read_fh; | 1095 | t->fdx = read_fdi; |
1112 | read_fdi->et = GNUNET_SCHEDULER_ET_IN; | ||
1113 | } | 1096 | } |
1114 | else if (NULL != write_fh) | 1097 | else if (NULL != write_fh) |
1115 | { | 1098 | { |
1116 | struct GNUNET_SCHEDULER_FdInfo *write_fdi = &t->fdx; | 1099 | struct GNUNET_SCHEDULER_FdInfo write_fdi = { .fh = write_fh, .et = GNUNET_SCHEDULER_ET_OUT, .sock = GNUNET_NETWORK_get_fd (write_nh)}; |
1117 | write_fdi->fh = write_fh; | 1100 | t->fdx = write_fdi; |
1118 | write_fdi->et = GNUNET_SCHEDULER_ET_OUT; | ||
1119 | } | 1101 | } |
1120 | } | 1102 | } |
1121 | 1103 | ||
1104 | /** | ||
1105 | * Cancel the task with the specified identifier. | ||
1106 | * The task must not yet have run. | ||
1107 | * | ||
1108 | * @param task id of the task to cancel | ||
1109 | * @return original closure of the task | ||
1110 | */ | ||
1122 | void * | 1111 | void * |
1123 | GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task) | 1112 | GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task) |
1124 | { | 1113 | { |
1125 | enum GNUNET_SCHEDULER_Priority p; | 1114 | enum GNUNET_SCHEDULER_Priority p; |
1126 | void *ret; | 1115 | void *ret; |
1127 | struct GNUNET_SCHEDULER_FdInfo *fdi; | ||
1128 | 1116 | ||
1129 | GNUNET_assert ( (NULL != active_task) || | 1117 | GNUNET_assert ( (NULL != active_task) || |
1130 | (GNUNET_NO == task->lifeness) ); | 1118 | (GNUNET_NO == task->lifeness) ); |
@@ -1148,12 +1136,7 @@ GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task) | |||
1148 | } | 1136 | } |
1149 | else | 1137 | else |
1150 | { | 1138 | { |
1151 | /*GNUNET_CONTAINER_DLL_remove (pending_head, | 1139 | scheduler_multi_function_call(task, scheduler_driver->del); |
1152 | pending_tail, | ||
1153 | task);*/ | ||
1154 | fdi = GNUNET_new (struct GNUNET_SCHEDULER_FdInfo); | ||
1155 | initFdInfo(fdi, task); | ||
1156 | scheduler_driver->del(scheduler_driver->cls, task, fdi); | ||
1157 | } | 1140 | } |
1158 | } | 1141 | } |
1159 | else | 1142 | else |
@@ -1496,6 +1479,20 @@ GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness, | |||
1496 | } | 1479 | } |
1497 | 1480 | ||
1498 | 1481 | ||
1482 | |||
1483 | int scheduler_multi_function_call(struct GNUNET_SCHEDULER_Task *t, int (*driver_func)()) | ||
1484 | { | ||
1485 | if (t->fds_len > 1){ | ||
1486 | int success = GNUNET_YES; | ||
1487 | for (int i = 0; i < t->fds_len;i++){ | ||
1488 | success = driver_func(scheduler_driver->cls, t , t->fds+i) && success; | ||
1489 | } | ||
1490 | return success; | ||
1491 | }else{ | ||
1492 | return driver_func(scheduler_driver->cls, t , t->fds); | ||
1493 | } | ||
1494 | } | ||
1495 | |||
1499 | /** | 1496 | /** |
1500 | * Schedule a new task to be run with a specified delay or when any of | 1497 | * Schedule a new task to be run with a specified delay or when any of |
1501 | * the specified file descriptor sets is ready. The delay can be used | 1498 | * the specified file descriptor sets is ready. The delay can be used |
@@ -1525,10 +1522,10 @@ GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness, | |||
1525 | static struct GNUNET_SCHEDULER_Task * | 1522 | static struct GNUNET_SCHEDULER_Task * |
1526 | add_without_sets (struct GNUNET_TIME_Relative delay, | 1523 | add_without_sets (struct GNUNET_TIME_Relative delay, |
1527 | enum GNUNET_SCHEDULER_Priority priority, | 1524 | enum GNUNET_SCHEDULER_Priority priority, |
1528 | struct GNUNET_NETWORK_Handle *read_nh, | 1525 | const struct GNUNET_NETWORK_Handle *read_nh, |
1529 | struct GNUNET_NETWORK_Handle *write_nh, | 1526 | const struct GNUNET_NETWORK_Handle *write_nh, |
1530 | struct GNUNET_DISK_FileHandle *read_fh, | 1527 | const struct GNUNET_DISK_FileHandle *read_fh, |
1531 | struct GNUNET_DISK_FileHandle *write_fh, | 1528 | const struct GNUNET_DISK_FileHandle *write_fh, |
1532 | //int rfd, | 1529 | //int rfd, |
1533 | //int wfd, | 1530 | //int wfd, |
1534 | GNUNET_SCHEDULER_TaskCallback task, | 1531 | GNUNET_SCHEDULER_TaskCallback task, |
@@ -1538,7 +1535,8 @@ add_without_sets (struct GNUNET_TIME_Relative delay, | |||
1538 | 1535 | ||
1539 | GNUNET_assert (NULL != active_task); | 1536 | GNUNET_assert (NULL != active_task); |
1540 | GNUNET_assert (NULL != task); | 1537 | GNUNET_assert (NULL != task); |
1541 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); | 1538 | t= initFdInfo (read_nh, write_nh, read_fh, write_fh); |
1539 | |||
1542 | t->callback = task; | 1540 | t->callback = task; |
1543 | t->callback_cls = task_cls; | 1541 | t->callback_cls = task_cls; |
1544 | #if DEBUG_FDS | 1542 | #if DEBUG_FDS |
@@ -1569,26 +1567,18 @@ add_without_sets (struct GNUNET_TIME_Relative delay, | |||
1569 | } | 1567 | } |
1570 | } | 1568 | } |
1571 | #endif | 1569 | #endif |
1572 | t->read_fd = rfd; | 1570 | |
1573 | GNUNET_assert (wfd >= -1); | ||
1574 | t->write_fd = wfd; | ||
1575 | #if PROFILE_DELAYS | 1571 | #if PROFILE_DELAYS |
1576 | t->start_time = GNUNET_TIME_absolute_get (); | 1572 | t->start_time = GNUNET_TIME_absolute_get (); |
1577 | #endif | 1573 | #endif |
1578 | t->timeout = GNUNET_TIME_relative_to_absolute (delay); | 1574 | t->timeout = GNUNET_TIME_relative_to_absolute (delay); |
1579 | t->priority = check_priority ((priority == GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : priority); | 1575 | t->priority = check_priority ((priority == GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : priority); |
1580 | t->lifeness = current_lifeness; | 1576 | t->lifeness = current_lifeness; |
1581 | //GNUNET_CONTAINER_DLL_insert (pending_head, | 1577 | |
1582 | // pending_tail, | 1578 | |
1583 | // t); | 1579 | |
1584 | //fdi = GNUNET_new (struct GNUNET_SCHEDULER_FdInfo); | 1580 | scheduler_multi_function_call(t, scheduler_driver->add); |
1585 | //initFdInfo(fdi, t); | 1581 | |
1586 | //scheduler_driver->add(scheduler_driver->cls, t , fdi); | ||
1587 | //initFdInfo (&t->fdx, read_nh, write_nh, read_fh, write_fh) | ||
1588 | initFdInfo (t, read_nh, write_nh, read_fh, write_fh); | ||
1589 | // FIXME: call add for each fdi if t->fds is a list | ||
1590 | scheduler_driver->add(scheduler_driver->cls, t , fdi); | ||
1591 | |||
1592 | max_priority_added = GNUNET_MAX (max_priority_added, | 1582 | max_priority_added = GNUNET_MAX (max_priority_added, |
1593 | t->priority); | 1583 | t->priority); |
1594 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1584 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1908,12 +1898,9 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio, | |||
1908 | GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : | 1898 | GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : |
1909 | prio); | 1899 | prio); |
1910 | t->lifeness = current_lifeness; | 1900 | t->lifeness = current_lifeness; |
1911 | /*GNUNET_CONTAINER_DLL_insert (pending_head, | 1901 | |
1912 | pending_tail, | 1902 | scheduler_multi_function_call(t, scheduler_driver->add); |
1913 | t);*/ | 1903 | |
1914 | fdi = GNUNET_new (struct GNUNET_SCHEDULER_FdInfo); | ||
1915 | initFdInfo(fdi, t); | ||
1916 | scheduler_driver->add(scheduler_driver->cls, t , fdi); | ||
1917 | max_priority_added = GNUNET_MAX (max_priority_added, | 1904 | max_priority_added = GNUNET_MAX (max_priority_added, |
1918 | t->priority); | 1905 | t->priority); |
1919 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1906 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -2089,6 +2076,7 @@ GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver, | |||
2089 | void *task_cls) | 2076 | void *task_cls) |
2090 | { | 2077 | { |
2091 | int ret; | 2078 | int ret; |
2079 | struct GNUNET_SCHEDULER_Handle sh; | ||
2092 | struct GNUNET_SIGNAL_Context *shc_int; | 2080 | struct GNUNET_SIGNAL_Context *shc_int; |
2093 | struct GNUNET_SIGNAL_Context *shc_term; | 2081 | struct GNUNET_SIGNAL_Context *shc_term; |
2094 | #if (SIGTERM != GNUNET_TERM_SIG) | 2082 | #if (SIGTERM != GNUNET_TERM_SIG) |
@@ -2158,7 +2146,7 @@ GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver, | |||
2158 | /* begin main event loop */ | 2146 | /* begin main event loop */ |
2159 | sh.rs = GNUNET_NETWORK_fdset_create (); | 2147 | sh.rs = GNUNET_NETWORK_fdset_create (); |
2160 | sh.ws = GNUNET_NETWORK_fdset_create (); | 2148 | sh.ws = GNUNET_NETWORK_fdset_create (); |
2161 | GNUNET_NETWORK_fdset_handle_set (rs, pr); | 2149 | GNUNET_NETWORK_fdset_handle_set (sh.rs, pr); |
2162 | sh.driver = driver; | 2150 | sh.driver = driver; |
2163 | ret = driver->loop (driver->cls, | 2151 | ret = driver->loop (driver->cls, |
2164 | &sh); | 2152 | &sh); |
@@ -2208,11 +2196,11 @@ int | |||
2208 | select_loop(void *cls, | 2196 | select_loop(void *cls, |
2209 | struct GNUNET_SCHEDULER_Handle *sh){ | 2197 | struct GNUNET_SCHEDULER_Handle *sh){ |
2210 | 2198 | ||
2211 | while_live(sh-rs, sh->ws); | 2199 | while_live(sh->rs, sh->ws); |
2212 | 2200 | ||
2213 | } | 2201 | } |
2214 | 2202 | ||
2215 | void | 2203 | static void |
2216 | select_set_wakeup(void *cls, | 2204 | select_set_wakeup(void *cls, |
2217 | struct GNUNET_TIME_Absolute dt){ | 2205 | struct GNUNET_TIME_Absolute dt){ |
2218 | 2206 | ||
@@ -2230,7 +2218,7 @@ const struct GNUNET_SCHEDULER_Driver * | |||
2230 | GNUNET_SCHEDULER_driver_select () | 2218 | GNUNET_SCHEDULER_driver_select () |
2231 | { | 2219 | { |
2232 | 2220 | ||
2233 | GNUNET_SCHEDULER_Driver *select_driver; | 2221 | struct GNUNET_SCHEDULER_Driver *select_driver; |
2234 | 2222 | ||
2235 | select_driver = GNUNET_new (struct GNUNET_SCHEDULER_Driver); | 2223 | select_driver = GNUNET_new (struct GNUNET_SCHEDULER_Driver); |
2236 | 2224 | ||