aboutsummaryrefslogtreecommitdiff
path: root/src/util/scheduler.c
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2019-05-10 20:08:01 +0200
committerFlorian Dold <florian.dold@gmail.com>2019-05-10 20:10:02 +0200
commitc1f06ac28fef5498952994e0399312b1fc567f22 (patch)
treead71f80bb08bfe20ff33880509263d78f334409b /src/util/scheduler.c
parentd1d18e6492708a0ce758ddd8c509f21b0ecbf6a0 (diff)
downloadgnunet-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.c43
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 */
2545void
2546GNUNET_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 */