diff options
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/common_logging.c | 83 | ||||
-rw-r--r-- | src/util/scheduler.c | 43 |
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 | */ | ||
103 | static __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 (¤t_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 | */ | ||
1585 | void | ||
1586 | GNUNET_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 | */ | ||
1600 | void | ||
1601 | GNUNET_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 | */ | ||
1612 | void | ||
1613 | GNUNET_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 | */ | ||
1626 | void | ||
1627 | GNUNET_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 | */ |
1553 | void __attribute__ ((constructor)) | 1636 | void __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 | */ | ||
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 */ |