1 cfg_trace! {
2     cfg_rt! {
3         use core::{
4             pin::Pin,
5             task::{Context, Poll},
6         };
7         use pin_project_lite::pin_project;
8         use std::future::Future;
9         pub(crate) use tracing::instrument::Instrumented;
10 
11         #[inline]
12         #[track_caller]
13         pub(crate) fn task<F>(task: F, kind: &'static str, name: Option<&str>) -> Instrumented<F> {
14             use tracing::instrument::Instrument;
15             let location = std::panic::Location::caller();
16             let span = tracing::trace_span!(
17                 target: "tokio::task",
18                 "runtime.spawn",
19                 %kind,
20                 task.name = %name.unwrap_or_default(),
21                 loc.file = location.file(),
22                 loc.line = location.line(),
23                 loc.col = location.column(),
24             );
25             task.instrument(span)
26         }
27 
28         pub(crate) fn async_op<P,F>(inner: P, resource_span: tracing::Span, source: &str, poll_op_name: &'static str, inherits_child_attrs: bool) -> InstrumentedAsyncOp<F>
29         where P: FnOnce() -> F {
30             resource_span.in_scope(|| {
31                 let async_op_span = tracing::trace_span!("runtime.resource.async_op", source = source, inherits_child_attrs = inherits_child_attrs);
32                 let enter = async_op_span.enter();
33                 let async_op_poll_span = tracing::trace_span!("runtime.resource.async_op.poll");
34                 let inner = inner();
35                 drop(enter);
36                 let tracing_ctx = AsyncOpTracingCtx {
37                     async_op_span,
38                     async_op_poll_span,
39                     resource_span: resource_span.clone(),
40                 };
41                 InstrumentedAsyncOp {
42                     inner,
43                     tracing_ctx,
44                     poll_op_name,
45                 }
46             })
47         }
48 
49         #[derive(Debug, Clone)]
50         pub(crate) struct AsyncOpTracingCtx {
51             pub(crate) async_op_span: tracing::Span,
52             pub(crate) async_op_poll_span: tracing::Span,
53             pub(crate) resource_span: tracing::Span,
54         }
55 
56 
57         pin_project! {
58             #[derive(Debug, Clone)]
59             pub(crate) struct InstrumentedAsyncOp<F> {
60                 #[pin]
61                 pub(crate) inner: F,
62                 pub(crate) tracing_ctx: AsyncOpTracingCtx,
63                 pub(crate) poll_op_name: &'static str
64             }
65         }
66 
67         impl<F: Future> Future for InstrumentedAsyncOp<F> {
68             type Output = F::Output;
69 
70             fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
71                 let this = self.project();
72                 let poll_op_name = &*this.poll_op_name;
73                 let _res_enter = this.tracing_ctx.resource_span.enter();
74                 let _async_op_enter = this.tracing_ctx.async_op_span.enter();
75                 let _async_op_poll_enter = this.tracing_ctx.async_op_poll_span.enter();
76                 trace_poll_op!(poll_op_name, this.inner.poll(cx))
77             }
78         }
79     }
80 }
81 cfg_time! {
82     #[track_caller]
83     pub(crate) fn caller_location() -> Option<&'static std::panic::Location<'static>> {
84         #[cfg(all(tokio_unstable, feature = "tracing"))]
85         return Some(std::panic::Location::caller());
86         #[cfg(not(all(tokio_unstable, feature = "tracing")))]
87         None
88     }
89 }
90 
91 cfg_not_trace! {
92     cfg_rt! {
93         #[inline]
94         pub(crate) fn task<F>(task: F, _: &'static str, _name: Option<&str>) -> F {
95             // nop
96             task
97         }
98     }
99 }
100