diff options
author | Florian Dold <florian.dold@gmail.com> | 2019-05-10 20:08:01 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2019-05-10 20:10:02 +0200 |
commit | c1f06ac28fef5498952994e0399312b1fc567f22 (patch) | |
tree | ad71f80bb08bfe20ff33880509263d78f334409b /src/util/scheduler.c | |
parent | d1d18e6492708a0ce758ddd8c509f21b0ecbf6a0 (diff) | |
download | gnunet-c1f06ac28fef5498952994e0399312b1fc567f22.tar.gz gnunet-c1f06ac28fef5498952994e0399312b1fc567f22.zip |
Implement asynchronous scope identifiers.
Without entering an asynchronous scope, logs are the same before. When
entering an asynchronous scope (either thread-based of
scheduler/task-based), all log lines within an asynchronous scope
contain its ID.
Currently this is only used in GNU Taler, for debugging requests across
multiple services. This allows us to get all log lines pertaining to a
particular request for a user or another service.
Diffstat (limited to 'src/util/scheduler.c')
-rw-r--r-- | src/util/scheduler.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/src/util/scheduler.c b/src/util/scheduler.c index 2ddbb8c60..c818e91ee 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c | |||
@@ -241,6 +241,11 @@ struct GNUNET_SCHEDULER_Task | |||
241 | int num_backtrace_strings; | 241 | int num_backtrace_strings; |
242 | #endif | 242 | #endif |
243 | 243 | ||
244 | /** | ||
245 | * Asynchronous scope of the task that scheduled this scope, | ||
246 | */ | ||
247 | struct GNUNET_AsyncScopeSave scope; | ||
248 | |||
244 | }; | 249 | }; |
245 | 250 | ||
246 | 251 | ||
@@ -1105,6 +1110,7 @@ GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at, | |||
1105 | GNUNET_assert (NULL != scheduler_driver); | 1110 | GNUNET_assert (NULL != scheduler_driver); |
1106 | GNUNET_assert (NULL != task); | 1111 | GNUNET_assert (NULL != task); |
1107 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); | 1112 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); |
1113 | GNUNET_async_scope_get (&t->scope); | ||
1108 | t->callback = task; | 1114 | t->callback = task; |
1109 | t->callback_cls = task_cls; | 1115 | t->callback_cls = task_cls; |
1110 | t->read_fd = -1; | 1116 | t->read_fd = -1; |
@@ -1293,6 +1299,7 @@ GNUNET_SCHEDULER_add_shutdown (GNUNET_SCHEDULER_TaskCallback task, | |||
1293 | GNUNET_assert (NULL != scheduler_driver); | 1299 | GNUNET_assert (NULL != scheduler_driver); |
1294 | GNUNET_assert (NULL != task); | 1300 | GNUNET_assert (NULL != task); |
1295 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); | 1301 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); |
1302 | GNUNET_async_scope_get (&t->scope); | ||
1296 | t->callback = task; | 1303 | t->callback = task; |
1297 | t->callback_cls = task_cls; | 1304 | t->callback_cls = task_cls; |
1298 | t->read_fd = -1; | 1305 | t->read_fd = -1; |
@@ -1411,6 +1418,7 @@ add_without_sets (struct GNUNET_TIME_Relative delay, | |||
1411 | GNUNET_assert (NULL != scheduler_driver); | 1418 | GNUNET_assert (NULL != scheduler_driver); |
1412 | GNUNET_assert (NULL != task); | 1419 | GNUNET_assert (NULL != task); |
1413 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); | 1420 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); |
1421 | GNUNET_async_scope_get (&t->scope); | ||
1414 | init_fd_info (t, | 1422 | init_fd_info (t, |
1415 | &read_nh, | 1423 | &read_nh, |
1416 | read_nh ? 1 : 0, | 1424 | read_nh ? 1 : 0, |
@@ -1882,6 +1890,7 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio, | |||
1882 | task, | 1890 | task, |
1883 | task_cls); | 1891 | task_cls); |
1884 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); | 1892 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); |
1893 | GNUNET_async_scope_get (&t->scope); | ||
1885 | init_fd_info (t, | 1894 | init_fd_info (t, |
1886 | read_nhandles, | 1895 | read_nhandles, |
1887 | read_nhandles_len, | 1896 | read_nhandles_len, |
@@ -2114,7 +2123,15 @@ GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh) | |||
2114 | "Running task %p\n", | 2123 | "Running task %p\n", |
2115 | pos); | 2124 | pos); |
2116 | GNUNET_assert (NULL != pos->callback); | 2125 | GNUNET_assert (NULL != pos->callback); |
2117 | pos->callback (pos->callback_cls); | 2126 | { |
2127 | struct GNUNET_AsyncScopeSave old_scope; | ||
2128 | if (pos->scope.have_scope) | ||
2129 | GNUNET_async_scope_enter (&pos->scope.scope_id, &old_scope); | ||
2130 | else | ||
2131 | GNUNET_async_scope_get (&old_scope); | ||
2132 | pos->callback (pos->callback_cls); | ||
2133 | GNUNET_async_scope_restore (&old_scope); | ||
2134 | } | ||
2118 | if (NULL != pos->fds) | 2135 | if (NULL != pos->fds) |
2119 | { | 2136 | { |
2120 | int del_result = scheduler_driver->del (scheduler_driver->cls, pos); | 2137 | int del_result = scheduler_driver->del (scheduler_driver->cls, pos); |
@@ -2513,4 +2530,28 @@ GNUNET_SCHEDULER_driver_select () | |||
2513 | } | 2530 | } |
2514 | 2531 | ||
2515 | 2532 | ||
2533 | /** | ||
2534 | * Change the async scope for the currently executing task and (transitively) | ||
2535 | * for all tasks scheduled by the current task after calling this function. | ||
2536 | * Nested tasks can begin their own nested async scope. | ||
2537 | * | ||
2538 | * Once the current task is finished, the async scope ID is reset to | ||
2539 | * its previous value. | ||
2540 | * | ||
2541 | * Must only be called from a running task. | ||
2542 | * | ||
2543 | * @param aid the asynchronous scope id to enter | ||
2544 | */ | ||
2545 | void | ||
2546 | GNUNET_SCHEDULER_begin_async_scope (struct GNUNET_AsyncScopeId *aid) | ||
2547 | { | ||
2548 | struct GNUNET_AsyncScopeSave dummy_old_scope; | ||
2549 | |||
2550 | GNUNET_assert (NULL != active_task); | ||
2551 | /* Since we're in a task, the context will be automatically | ||
2552 | restored by the scheduler. */ | ||
2553 | GNUNET_async_scope_enter (aid, &dummy_old_scope); | ||
2554 | } | ||
2555 | |||
2556 | |||
2516 | /* end of scheduler.c */ | 2557 | /* end of scheduler.c */ |