aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/common_logging.c83
-rw-r--r--src/util/scheduler.c43
2 files changed, 125 insertions, 1 deletions
diff --git a/src/util/common_logging.c b/src/util/common_logging.c
index 77a595878..5052134f8 100644
--- a/src/util/common_logging.c
+++ b/src/util/common_logging.c
@@ -95,6 +95,13 @@ struct CustomLogger
95 void *logger_cls; 95 void *logger_cls;
96}; 96};
97 97
98
99/**
100 * Asynchronous scope of the current thread, or NULL if we have not
101 * entered an async scope yet.
102 */
103static __thread struct GNUNET_AsyncScopeSave current_async_scope;
104
98/** 105/**
99 * The last "bulk" error message that we have been logging. 106 * The last "bulk" error message that we have been logging.
100 * Note that this message maybe truncated to the first BULK_TRACK_SIZE 107 * Note that this message maybe truncated to the first BULK_TRACK_SIZE
@@ -838,6 +845,28 @@ output_message (enum GNUNET_ErrorType kind,
838 "* %s", 845 "* %s",
839 msg); 846 msg);
840 } 847 }
848 else if (GNUNET_YES == current_async_scope.have_scope)
849 {
850 static GNUNET_THREAD_LOCAL char id_buf[27];
851 char *end;
852
853 /* We're logging, so skip_log must be currently 0. */
854 skip_log = 100;
855 end = GNUNET_STRINGS_data_to_string (&current_async_scope.scope_id,
856 sizeof (struct GNUNET_AsyncScopeId),
857 id_buf,
858 sizeof (id_buf) - 1);
859 GNUNET_assert (NULL != end);
860 *end = '\0';
861 skip_log = 0;
862 FPRINTF (GNUNET_stderr,
863 "%s %s(%s) %s %s",
864 datestr,
865 comp,
866 id_buf,
867 GNUNET_error_type_to_string (kind),
868 msg);
869 }
841 else 870 else
842 { 871 {
843 FPRINTF (GNUNET_stderr, 872 FPRINTF (GNUNET_stderr,
@@ -1548,6 +1577,60 @@ GNUNET_log_config_invalid (enum GNUNET_ErrorType kind,
1548 1577
1549 1578
1550/** 1579/**
1580 * Set the async scope for the current thread.
1581 *
1582 * @param aid the async scope identifier
1583 * @param old_scope[out] location to save the old scope
1584 */
1585void
1586GNUNET_async_scope_enter (const struct GNUNET_AsyncScopeId *aid,
1587 struct GNUNET_AsyncScopeSave *old_scope)
1588{
1589 *old_scope = current_async_scope;
1590 current_async_scope.have_scope = GNUNET_YES;
1591 current_async_scope.scope_id = *aid;
1592}
1593
1594
1595/**
1596 * Clear the current thread's async scope.
1597 *
1598 * @param old_scope scope to restore
1599 */
1600void
1601GNUNET_async_scope_restore (struct GNUNET_AsyncScopeSave *old_scope)
1602{
1603 current_async_scope = *old_scope;
1604}
1605
1606
1607/**
1608 * Generate a fresh async scope identifier.
1609 *
1610 * @param[out] aid_ret pointer to where the result is stored
1611 */
1612void
1613GNUNET_async_scope_fresh (struct GNUNET_AsyncScopeId *aid_ret)
1614{
1615 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
1616 aid_ret,
1617 sizeof (struct GNUNET_AsyncScopeId));
1618}
1619
1620
1621/**
1622 * Get the current async scope.
1623 *
1624 * @param[out] scope_ret pointer to where the result is stored
1625 */
1626void
1627GNUNET_async_scope_get (struct GNUNET_AsyncScopeSave *scope_ret)
1628{
1629 *scope_ret = current_async_scope;
1630}
1631
1632
1633/**
1551 * Initializer 1634 * Initializer
1552 */ 1635 */
1553void __attribute__ ((constructor)) 1636void __attribute__ ((constructor))
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 */