diff options
author | lurchi <lurchi@strangeplace.net> | 2017-08-18 16:17:28 +0200 |
---|---|---|
committer | lurchi <lurchi@strangeplace.net> | 2017-08-18 16:17:28 +0200 |
commit | e29921e503d8da33f0b9b15302288c5572ec9bf4 (patch) | |
tree | 0bf5efe2ea136fd292ffc6699214b2800cd09ef4 /src | |
parent | 59837ecc5f54c39322cc5afba2dfc9fed154a8fe (diff) | |
download | gnunet-e29921e503d8da33f0b9b15302288c5572ec9bf4.tar.gz gnunet-e29921e503d8da33f0b9b15302288c5572ec9bf4.zip |
implement bookkeeping about which FDs related to a tasks have been marked ready (required API change in GNUNET_SCHEDULER_task_ready)
Diffstat (limited to 'src')
-rw-r--r-- | src/include/gnunet_scheduler_lib.h | 4 | ||||
-rw-r--r-- | src/util/scheduler.c | 139 |
2 files changed, 86 insertions, 57 deletions
diff --git a/src/include/gnunet_scheduler_lib.h b/src/include/gnunet_scheduler_lib.h index dea0a006a..5f9389726 100644 --- a/src/include/gnunet_scheduler_lib.h +++ b/src/include/gnunet_scheduler_lib.h | |||
@@ -222,11 +222,11 @@ struct GNUNET_SCHEDULER_TaskContext | |||
222 | * that the task is ready (with the respective priority). | 222 | * that the task is ready (with the respective priority). |
223 | * | 223 | * |
224 | * @param task the task that is ready | 224 | * @param task the task that is ready |
225 | * @param et information about why the task is ready | 225 | * @param fdi information about the related FD |
226 | */ | 226 | */ |
227 | void | 227 | void |
228 | GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task, | 228 | GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task, |
229 | enum GNUNET_SCHEDULER_EventType et); | 229 | struct GNUNET_SCHEDULER_FdInfo *fdi); |
230 | 230 | ||
231 | 231 | ||
232 | /** | 232 | /** |
diff --git a/src/util/scheduler.c b/src/util/scheduler.c index 19ec4efeb..33aba9ad6 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c | |||
@@ -148,6 +148,24 @@ struct GNUNET_SCHEDULER_Task | |||
148 | * Absolute timeout value for the task, or | 148 | * Absolute timeout value for the task, or |
149 | * #GNUNET_TIME_UNIT_FOREVER_ABS for "no timeout". | 149 | * #GNUNET_TIME_UNIT_FOREVER_ABS for "no timeout". |
150 | */ | 150 | */ |
151 | |||
152 | /** | ||
153 | * Size of the @e fds array. | ||
154 | */ | ||
155 | unsigned int fds_len; | ||
156 | |||
157 | /** | ||
158 | * if this task is related to multiple FDs this array contains | ||
159 | * all FdInfo structs that were marked as ready by calling | ||
160 | * #GNUNET_SCHEDULER_task_ready | ||
161 | */ | ||
162 | struct GNUNET_SCHEDULER_FdInfo *ready_fds; | ||
163 | |||
164 | /** | ||
165 | * Size of the @e ready_fds array | ||
166 | */ | ||
167 | unsigned int ready_fds_len; | ||
168 | |||
151 | struct GNUNET_TIME_Absolute timeout; | 169 | struct GNUNET_TIME_Absolute timeout; |
152 | 170 | ||
153 | #if PROFILE_DELAYS | 171 | #if PROFILE_DELAYS |
@@ -158,11 +176,6 @@ struct GNUNET_SCHEDULER_Task | |||
158 | #endif | 176 | #endif |
159 | 177 | ||
160 | /** | 178 | /** |
161 | * Size of the @e fds array. | ||
162 | */ | ||
163 | unsigned int fds_len; | ||
164 | |||
165 | /** | ||
166 | * Why is the task ready? Set after task is added to ready queue. | 179 | * Why is the task ready? Set after task is added to ready queue. |
167 | * Initially set to zero. All reasons that have already been | 180 | * Initially set to zero. All reasons that have already been |
168 | * satisfied (i.e. read or write ready) will be set over time. | 181 | * satisfied (i.e. read or write ready) will be set over time. |
@@ -476,6 +489,29 @@ GNUNET_SCHEDULER_shutdown () | |||
476 | } | 489 | } |
477 | 490 | ||
478 | 491 | ||
492 | static void | ||
493 | destroy_fd_info_list (struct GNUNET_SCHEDULER_FdInfo *fds, unsigned int fds_len) | ||
494 | { | ||
495 | unsigned int i; | ||
496 | for (i = 0; i != fds_len; ++i) | ||
497 | { | ||
498 | const struct GNUNET_SCHEDULER_FdInfo *fdi = fds + i; | ||
499 | if (fdi->fd) | ||
500 | { | ||
501 | GNUNET_NETWORK_socket_free_memory_only_ ((struct GNUNET_NETWORK_Handle *) fdi->fd); | ||
502 | } | ||
503 | if (fdi->fh) | ||
504 | { | ||
505 | // FIXME: on WIN32 this is not enough! A function | ||
506 | // GNUNET_DISK_file_free_memory_only would be nice | ||
507 | GNUNET_free ((void *) fdi->fh); | ||
508 | } | ||
509 | } | ||
510 | /* free the array */ | ||
511 | GNUNET_array_grow (fds, fds_len, 0); | ||
512 | } | ||
513 | |||
514 | |||
479 | /** | 515 | /** |
480 | * Destroy a task (release associated resources) | 516 | * Destroy a task (release associated resources) |
481 | * | 517 | * |
@@ -484,31 +520,16 @@ GNUNET_SCHEDULER_shutdown () | |||
484 | static void | 520 | static void |
485 | destroy_task (struct GNUNET_SCHEDULER_Task *t) | 521 | destroy_task (struct GNUNET_SCHEDULER_Task *t) |
486 | { | 522 | { |
487 | // FIXME: destroy fds! | ||
488 | if (t->fds_len > 1) | 523 | if (t->fds_len > 1) |
489 | { | 524 | { |
490 | size_t i; | 525 | destroy_fd_info_list ((struct GNUNET_SCHEDULER_FdInfo *) t->fds, |
491 | for (i = 0; i != t->fds_len; ++i) | 526 | t->fds_len); |
492 | { | 527 | } |
493 | const struct GNUNET_SCHEDULER_FdInfo *fdi = t->fds + i; | 528 | if (t->ready_fds_len > 0) |
494 | if (fdi->fd) | 529 | { |
495 | { | 530 | destroy_fd_info_list ((struct GNUNET_SCHEDULER_FdInfo *) t->ready_fds, |
496 | GNUNET_NETWORK_socket_free_memory_only_ ((struct GNUNET_NETWORK_Handle *) fdi->fd); | 531 | t->ready_fds_len); |
497 | } | ||
498 | if (fdi->fh) | ||
499 | { | ||
500 | // FIXME: on WIN32 this is not enough! A function | ||
501 | // GNUNET_DISK_file_free_memory_only would be nice | ||
502 | GNUNET_free ((void *) fdi->fh); | ||
503 | } | ||
504 | } | ||
505 | /* free the array */ | ||
506 | GNUNET_array_grow (t->fds, t->fds_len, 0); | ||
507 | } | 532 | } |
508 | //if (NULL != t->read_set) | ||
509 | // GNUNET_NETWORK_fdset_destroy (t->read_set); | ||
510 | //if (NULL != t->write_set) | ||
511 | // GNUNET_NETWORK_fdset_destroy (t->write_set); | ||
512 | #if EXECINFO | 533 | #if EXECINFO |
513 | GNUNET_free (t->backtrace_strings); | 534 | GNUNET_free (t->backtrace_strings); |
514 | #endif | 535 | #endif |
@@ -1318,11 +1339,6 @@ add_without_sets (struct GNUNET_TIME_Relative delay, | |||
1318 | read_fh ? 1 : 0, | 1339 | read_fh ? 1 : 0, |
1319 | &write_fh, | 1340 | &write_fh, |
1320 | write_fh ? 1 : 0); | 1341 | write_fh ? 1 : 0); |
1321 | |||
1322 | //int read_fds[2] = {GNUNET_NETWORK_get_fd (read_nh), read_fh->fd}; | ||
1323 | //int write_fds[2] = {GNUNET_NETWORK_get_fd (write_nh), write_fh->fd}; | ||
1324 | //init_fd_info (t, read_fds, 2, write_fds, 2); | ||
1325 | //init_fd_info (t, read_nh, write_nh, read_fh, write_fh); | ||
1326 | t->callback = task; | 1342 | t->callback = task; |
1327 | t->callback_cls = task_cls; | 1343 | t->callback_cls = task_cls; |
1328 | #if DEBUG_FDS | 1344 | #if DEBUG_FDS |
@@ -1826,11 +1842,11 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio, | |||
1826 | * that the task is ready (with the respective priority). | 1842 | * that the task is ready (with the respective priority). |
1827 | * | 1843 | * |
1828 | * @param task the task that is ready, NULL for wake up calls | 1844 | * @param task the task that is ready, NULL for wake up calls |
1829 | * @param et information about why the task is ready | 1845 | * @param fdi information about the related FD |
1830 | */ | 1846 | */ |
1831 | void | 1847 | void |
1832 | GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task, | 1848 | GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task, |
1833 | enum GNUNET_SCHEDULER_EventType et) | 1849 | struct GNUNET_SCHEDULER_FdInfo *fdi) |
1834 | { | 1850 | { |
1835 | enum GNUNET_SCHEDULER_Reason reason; | 1851 | enum GNUNET_SCHEDULER_Reason reason; |
1836 | struct GNUNET_TIME_Absolute now; | 1852 | struct GNUNET_TIME_Absolute now; |
@@ -1840,24 +1856,24 @@ GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task, | |||
1840 | if (now.abs_value_us >= task->timeout.abs_value_us) | 1856 | if (now.abs_value_us >= task->timeout.abs_value_us) |
1841 | reason |= GNUNET_SCHEDULER_REASON_TIMEOUT; | 1857 | reason |= GNUNET_SCHEDULER_REASON_TIMEOUT; |
1842 | if ( (0 == (reason & GNUNET_SCHEDULER_REASON_READ_READY)) && | 1858 | if ( (0 == (reason & GNUNET_SCHEDULER_REASON_READ_READY)) && |
1843 | (0 != (GNUNET_SCHEDULER_ET_IN & et)) ) | 1859 | (0 != (GNUNET_SCHEDULER_ET_IN & fdi->et)) ) |
1844 | reason |= GNUNET_SCHEDULER_REASON_READ_READY; | 1860 | reason |= GNUNET_SCHEDULER_REASON_READ_READY; |
1845 | if ( (0 == (reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) && | 1861 | if ( (0 == (reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) && |
1846 | (0 != (GNUNET_SCHEDULER_ET_OUT & et)) ) | 1862 | (0 != (GNUNET_SCHEDULER_ET_OUT & fdi->et)) ) |
1847 | reason |= GNUNET_SCHEDULER_REASON_WRITE_READY; | 1863 | reason |= GNUNET_SCHEDULER_REASON_WRITE_READY; |
1848 | reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE; | 1864 | reason |= GNUNET_SCHEDULER_REASON_PREREQ_DONE; |
1849 | |||
1850 | |||
1851 | |||
1852 | |||
1853 | task->reason = reason; | 1865 | task->reason = reason; |
1854 | task->fds = &task->fdx; // FIXME: if task contains a list of fds, this is wrong! | 1866 | if (task->fds_len > 1) |
1855 | task->fdx.et = et; | 1867 | { |
1856 | task->fds_len = 1; | 1868 | GNUNET_array_append (task->ready_fds, task->ready_fds_len, *fdi); |
1857 | GNUNET_CONTAINER_DLL_remove (pending_head, | 1869 | } |
1858 | pending_tail, | 1870 | if (GNUNET_NO == task->in_ready_list) |
1859 | task); | 1871 | { |
1860 | queue_ready_task (task); | 1872 | GNUNET_CONTAINER_DLL_remove (pending_head, |
1873 | pending_tail, | ||
1874 | task); | ||
1875 | queue_ready_task (task); | ||
1876 | } | ||
1861 | } | 1877 | } |
1862 | 1878 | ||
1863 | 1879 | ||
@@ -1884,6 +1900,7 @@ GNUNET_SCHEDULER_run_from_driver (struct GNUNET_SCHEDULER_Handle *sh) | |||
1884 | enum GNUNET_SCHEDULER_Priority p; | 1900 | enum GNUNET_SCHEDULER_Priority p; |
1885 | struct GNUNET_SCHEDULER_Task *pos; | 1901 | struct GNUNET_SCHEDULER_Task *pos; |
1886 | struct GNUNET_TIME_Absolute now; | 1902 | struct GNUNET_TIME_Absolute now; |
1903 | int i; | ||
1887 | 1904 | ||
1888 | /* check for tasks that reached the timeout! */ | 1905 | /* check for tasks that reached the timeout! */ |
1889 | now = GNUNET_TIME_absolute_get (); | 1906 | now = GNUNET_TIME_absolute_get (); |
@@ -1942,20 +1959,32 @@ GNUNET_SCHEDULER_run_from_driver (struct GNUNET_SCHEDULER_Handle *sh) | |||
1942 | tc.reason = pos->reason; | 1959 | tc.reason = pos->reason; |
1943 | GNUNET_NETWORK_fdset_zero (sh->rs); | 1960 | GNUNET_NETWORK_fdset_zero (sh->rs); |
1944 | GNUNET_NETWORK_fdset_zero (sh->ws); | 1961 | GNUNET_NETWORK_fdset_zero (sh->ws); |
1945 | tc.fds_len = pos->fds_len; | 1962 | tc.fds_len = pos->ready_fds_len; |
1946 | tc.fds = pos->fds; | 1963 | tc.fds = pos->ready_fds; |
1947 | //tc.read_ready = (NULL == pos->read_set) ? sh->rs : pos->read_set; | 1964 | for (i = 0; i != pos->ready_fds_len; ++i) |
1948 | tc.read_ready = sh->rs; | 1965 | { |
1966 | struct GNUNET_SCHEDULER_FdInfo *fdi = pos->ready_fds + i; | ||
1967 | if (GNUNET_SCHEDULER_ET_IN == fdi->et) | ||
1968 | { | ||
1969 | GNUNET_NETWORK_fdset_set_native (sh->rs, | ||
1970 | fdi->sock); | ||
1971 | } | ||
1972 | else if (GNUNET_SCHEDULER_ET_OUT == fdi->et) | ||
1973 | { | ||
1974 | GNUNET_NETWORK_fdset_set_native (sh->ws, | ||
1975 | fdi->sock); | ||
1976 | } | ||
1977 | } | ||
1949 | if ( (-1 != pos->read_fd) && | 1978 | if ( (-1 != pos->read_fd) && |
1950 | (0 != (pos->reason & GNUNET_SCHEDULER_REASON_READ_READY)) ) | 1979 | (0 != (pos->reason & GNUNET_SCHEDULER_REASON_READ_READY)) ) |
1951 | GNUNET_NETWORK_fdset_set_native (sh->rs, | 1980 | GNUNET_NETWORK_fdset_set_native (sh->rs, |
1952 | pos->read_fd); | 1981 | pos->read_fd); |
1953 | //tc.write_ready = (NULL == pos->write_set) ? sh->ws : pos->write_set; | ||
1954 | tc.write_ready = sh->ws; | ||
1955 | if ( (-1 != pos->write_fd) && | 1982 | if ( (-1 != pos->write_fd) && |
1956 | (0 != (pos->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ) | 1983 | (0 != (pos->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ) |
1957 | GNUNET_NETWORK_fdset_set_native (sh->ws, | 1984 | GNUNET_NETWORK_fdset_set_native (sh->ws, |
1958 | pos->write_fd); | 1985 | pos->write_fd); |
1986 | tc.read_ready = sh->rs; | ||
1987 | tc.write_ready = sh->ws; | ||
1959 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1988 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1960 | "Running task %p\n", | 1989 | "Running task %p\n", |
1961 | pos); | 1990 | pos); |
@@ -2309,7 +2338,7 @@ select_loop (void *cls, | |||
2309 | GNUNET_CONTAINER_DLL_remove (context->scheduled_in_head, | 2338 | GNUNET_CONTAINER_DLL_remove (context->scheduled_in_head, |
2310 | context->scheduled_in_tail, | 2339 | context->scheduled_in_tail, |
2311 | pos); | 2340 | pos); |
2312 | GNUNET_SCHEDULER_task_ready (pos->task, GNUNET_SCHEDULER_ET_IN); | 2341 | GNUNET_SCHEDULER_task_ready (pos->task, pos->fdi); |
2313 | } | 2342 | } |
2314 | } | 2343 | } |
2315 | for (pos = context->scheduled_out_head; NULL != pos; pos = pos->next) | 2344 | for (pos = context->scheduled_out_head; NULL != pos; pos = pos->next) |
@@ -2319,7 +2348,7 @@ select_loop (void *cls, | |||
2319 | GNUNET_CONTAINER_DLL_remove (context->scheduled_out_head, | 2348 | GNUNET_CONTAINER_DLL_remove (context->scheduled_out_head, |
2320 | context->scheduled_out_tail, | 2349 | context->scheduled_out_tail, |
2321 | pos); | 2350 | pos); |
2322 | GNUNET_SCHEDULER_task_ready (pos->task, GNUNET_SCHEDULER_ET_OUT); | 2351 | GNUNET_SCHEDULER_task_ready (pos->task, pos->fdi); |
2323 | } | 2352 | } |
2324 | } | 2353 | } |
2325 | int tasks_ready = GNUNET_SCHEDULER_run_from_driver (sh); | 2354 | int tasks_ready = GNUNET_SCHEDULER_run_from_driver (sh); |