Coverage Report

Created: 2024-10-22 12:33

/build/source/nativelink-util/src/origin_context.rs
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2024 The NativeLink Authors. All rights reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//    http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
use core::panic;
16
use std::any::Any;
17
use std::cell::RefCell;
18
use std::clone::Clone;
19
use std::collections::HashMap;
20
use std::mem::ManuallyDrop;
21
use std::pin::Pin;
22
use std::sync::Arc;
23
use std::task::{Context, Poll};
24
25
use futures::Future;
26
use nativelink_error::{make_err, Code, Error};
27
use pin_project_lite::pin_project;
28
use tracing::instrument::Instrumented;
29
use tracing::{Instrument, Span};
30
31
use crate::background_spawn;
32
33
/// Make a symbol that represents a unique memory pointer that is
34
/// constant and choosen at compile time. This enables two modules
35
/// to use that memory location to reference data that lives in a
36
/// shared module without the two modules knowing about eachother.
37
/// For example, lets say we have a context that holds anonymous
38
/// data; we can use these symbols to let one module set the data
39
/// and tie the data to a symbol and another module read the data
40
/// with the symbol, without the two modules knowing about eachother.
41
#[macro_export]
42
macro_rules! make_symbol {
43
    ($name:ident, $type:ident) => {
44
        #[no_mangle]
45
        #[used]
46
        pub static $name: $crate::origin_context::NLSymbol<$type> =
47
            $crate::origin_context::NLSymbol {
48
                name: concat!(module_path!(), "::", stringify!($name)),
49
                _phantom: std::marker::PhantomData {},
50
            };
51
    };
52
}
53
54
pub struct NLSymbol<T: Send + Sync + 'static> {
55
    pub name: &'static str,
56
    pub _phantom: std::marker::PhantomData<T>,
57
}
58
59
impl<T: Send + Sync + 'static> Symbol for NLSymbol<T> {
60
    type Type = T;
61
62
0
    fn name(&self) -> &'static str {
63
0
        self.name
64
0
    }
65
}
66
67
pub type RawSymbol = std::os::raw::c_void;
68
69
pub trait Symbol {
70
    type Type: 'static;
71
72
0
    fn name(&self) -> &'static str {
73
0
        std::any::type_name::<Self>()
74
0
    }
75
76
45
    fn as_ptr(&'static self) -> *const RawSymbol {
77
45
        self as *const Self as *const RawSymbol
78
45
    }
79
}
80
81
/// Simple wrapper around a raw symbol pointer.
82
/// This allows us to bypass the unsafe undefined behavior check
83
/// when using raw pointers by manually implementing Send and Sync.
84
#[derive(Eq, PartialEq, Hash, Clone)]
85
#[repr(transparent)]
86
pub struct RawSymbolWrapper(pub *const RawSymbol);
87
88
unsafe impl Send for RawSymbolWrapper {}
89
unsafe impl Sync for RawSymbolWrapper {}
90
91
/// Context used to store data about the origin of a request.
92
#[derive(Default, Clone)]
93
pub struct OriginContext {
94
    data: HashMap<RawSymbolWrapper, Arc<dyn Any + Send + Sync + 'static>>,
95
}
96
97
impl OriginContext {
98
    /// Creates a new (empty) context.
99
301
    pub fn new() -> Self {
100
301
        Self::default()
101
301
    }
102
103
    /// Sets the value for a given symbol on the context.
104
40
    pub fn set_value<T: Any + Send + Sync + 'static>(
105
40
        &mut self,
106
40
        symbol: &'static impl Symbol<Type = T>,
107
40
        value: Arc<T>,
108
40
    ) -> Option<Arc<dyn Any + Send + Sync + 'static>> {
109
40
        self.data.insert(RawSymbolWrapper(symbol.as_ptr()), value)
110
40
    }
111
112
    /// Gets the value current set for a given symbol on the context.
113
    #[inline]
114
5
    pub fn get_value<T: Send + Sync + 'static>(
115
5
        &self,
116
5
        symbol: &'static impl Symbol<Type = T>,
117
5
    ) -> Result<Option<Arc<T>>, Error> {
118
5
        self.data
119
5
            .get(&RawSymbolWrapper(symbol.as_ptr()))
120
5
            .map_or(Ok(None), |value| {
121
2
                Arc::downcast::<T>(value.clone()).map_or_else(
122
2
                    |_| {
123
0
                        Err(make_err!(
124
0
                            Code::Internal,
125
0
                            "Failed to downcast symbol: {}",
126
0
                            symbol.name(),
127
0
                        ))
128
2
                    },
129
2
                    |v| Ok(Some(v)),
130
2
                )
131
5
            })
132
5
    }
133
134
    /// Consumes the context and runs the given function with the context set
135
    /// as the active context. When the function exists the context is restored
136
    /// to the previous global context.
137
    #[inline]
138
4
    pub fn run<T>(self, span: Span, func: impl FnOnce() -> T) -> T {
139
4
        Arc::new(self).wrap(span, func)()
140
4
    }
141
142
    /// Wraps a function so when it is called the passed in context is set as
143
    /// the active context and when the function exists the context is restored
144
    /// to the previous global context.
145
    #[inline]
146
4
    fn wrap<T>(self: Arc<Self>, span: Span, func: impl FnOnce() -> T) -> impl FnOnce() -> T {
147
4
        move || {
148
4
            let enter = Self::enter(self);
149
4
            let result = span.in_scope(func);
150
4
            enter.release();
151
4
            result
152
4
        }
153
4
    }
154
155
    /// Wraps a future so when it is called the passed in context is set as
156
    /// the active context and when the future exists the context is restored
157
    /// to the previous global context.
158
    #[inline]
159
337
    pub fn wrap_async<T>(
160
337
        self: Arc<Self>,
161
337
        span: Span,
162
337
        fut: impl Future<Output = T>,
163
337
    ) -> impl Future<Output = T> {
164
337
        ContextAwareFuture::new(Some(self), fut.instrument(span))
165
337
    }
166
167
    /// Spawns a future in the background with the given context.
168
0
    pub fn background_spawn(
169
0
        self: Arc<Self>,
170
0
        span: Span,
171
0
        fut: impl Future<Output = ()> + Send + 'static,
172
0
    ) {
173
0
        background_spawn!(span: span, ctx: Some(self), fut: fut);
174
0
    }
175
176
    /// Enters the context, storing the previous context. If the returned
177
    /// `ContextDropGuard` is dropped, the previous context is restored.
178
    #[inline]
179
16.6k
    fn enter(self: Arc<Self>) -> ContextDropGuard {
180
16.6k
        ContextDropGuard::new(self)
181
16.6k
    }
182
}
183
184
/// Static struct to interact with the active global context.
185
pub struct ActiveOriginContext;
186
187
impl ActiveOriginContext {
188
    /// Sets the active context for the current thread.
189
1.47k
    pub fn get() -> Option<Arc<OriginContext>> {
190
1.47k
        GLOBAL_ORIGIN_CONTEXT.with_borrow(Clone::clone)
191
1.47k
    }
192
193
    /// Gets the value current set for a given symbol on the
194
    /// active context.
195
    #[inline]
196
5
    pub fn get_value<T: Send + Sync + 'static>(
197
5
        symbol: &'static impl Symbol<Type = T>,
198
5
    ) -> Result<Option<Arc<T>>, Error> {
199
5
        GLOBAL_ORIGIN_CONTEXT.with_borrow(|maybe_ctx| {
200
5
            maybe_ctx.as_ref().map_or_else(
201
5
                || {
202
0
                    Err(make_err!(
203
0
                        Code::Internal,
204
0
                        "Expected active context to be set"
205
0
                    ))
206
5
                },
207
5
                |ctx| ctx.get_value(symbol),
208
5
            )
209
5
        })
210
5
    }
211
212
    /// Forks the active context, returning a new context with the same data.
213
    #[inline]
214
40
    pub fn fork() -> Result<OriginContext, Error> {
215
40
        GLOBAL_ORIGIN_CONTEXT.with_borrow(|maybe_ctx| {
216
40
            maybe_ctx.as_ref().map_or_else(
217
40
                || {
218
0
                    Err(make_err!(
219
0
                        Code::Internal,
220
0
                        "Expected active context to be set"
221
0
                    ))
222
40
                },
223
40
                |ctx| Ok(ctx.as_ref().clone()),
224
40
            )
225
40
        })
226
40
    }
227
}
228
229
thread_local! {
230
  /// Global context that is used to store the active context.
231
  static GLOBAL_ORIGIN_CONTEXT: RefCell<Option<Arc<OriginContext>>> = const { RefCell::new(None) };
232
}
233
234
/// Special guard struct that is used to hold the previous context and restore it
235
/// when the guard is released or dropped.
236
struct ContextDropGuard {
237
    prev_ctx: Option<Arc<OriginContext>>,
238
    new_ctx_ptr: *const OriginContext,
239
}
240
241
impl ContextDropGuard {
242
    /// Places the new context in the global context, stores the previous context
243
    /// and returns a new `ContextDropGuard`, so if it is ever released or dropped
244
    /// the previous context will be restored.
245
    #[inline]
246
16.6k
    fn new(new_ctx: Arc<OriginContext>) -> Self {
247
16.6k
        let new_ctx_ptr = Arc::as_ptr(&new_ctx);
248
16.6k
        let prev_ctx = GLOBAL_ORIGIN_CONTEXT.replace(Some(new_ctx));
249
16.6k
        Self {
250
16.6k
            prev_ctx,
251
16.6k
            new_ctx_ptr,
252
16.6k
        }
253
16.6k
    }
254
255
    /// Swap the global context with the previous context.
256
    /// Returns the context used in the `.enter()`/`.new()` call.
257
16.6k
    fn restore_global_context(&mut self) -> Arc<OriginContext> {
258
16.6k
        let new_ctx = GLOBAL_ORIGIN_CONTEXT
259
16.6k
            .replace(self.prev_ctx.take())
260
16.6k
            .expect("Expected global context to be set");
261
16.6k
        assert_eq!(self.new_ctx_ptr, Arc::as_ptr(&new_ctx));
262
16.6k
        new_ctx
263
16.6k
    }
264
265
    /// Release the context guard and restore the previous context.
266
    /// This is an optimization, so we don't need to clone our Arc
267
    /// if the caller can use the context after releasing it.
268
    #[inline]
269
14.8k
    fn release(mut self) -> Arc<OriginContext> {
270
14.8k
        let new_ctx = self.restore_global_context();
271
14.8k
        std::mem::forget(self); // Prevent the destructor from being called.
272
14.8k
        new_ctx
273
14.8k
    }
274
}
275
276
impl Drop for ContextDropGuard {
277
    #[inline]
278
1.80k
    fn drop(&mut self) {
279
1.80k
        // If the user calls `.release()` the drop() will not be triggered.
280
1.80k
        // If a panic happens, the drop() will be called and the `.release()`
281
1.80k
        // will not be called, this is our safety net.
282
1.80k
        self.restore_global_context();
283
1.80k
    }
284
}
285
286
pin_project! {
287
    #[must_use = "futures do nothing unless you `.await` or poll them"]
288
    pub struct ContextAwareFuture<F> {
289
        // `ManuallyDrop` is used so we can call `self.span.enter()` in the `drop()`
290
        // of our inner future, then drop the span.
291
        #[pin]
292
        inner: ManuallyDrop<Instrumented<F>>,
293
        context: Option<Arc<OriginContext>>,
294
    }
295
296
    impl <F> PinnedDrop for ContextAwareFuture<F> {
297
        #[inline]
298
        fn drop(this: Pin<&mut Self>) {
299
            let this = this.project();
300
            // Note: If the future panics, the context will not be restored, so
301
            // this is a best effort to provide access to our global context
302
            // in the desturctors the event of a panic.
303
            let _enter = this.context.take().map(OriginContext::enter);
304
            // SAFETY: 1. `Pin::get_unchecked_mut()` is safe, because this isn't
305
            //             different from wrapping `T` in `Option` and calling
306
            //             `Pin::set(&mut this.inner, None)`, except avoiding
307
            //             additional memory overhead.
308
            //         2. `ManuallyDrop::drop()` is safe, because
309
            //            `PinnedDrop::drop()` is guaranteed to be called only
310
            //            once.
311
            unsafe {
312
                ManuallyDrop::drop(this.inner.get_unchecked_mut());
313
            }
314
        }
315
    }
316
}
317
318
impl<T> ContextAwareFuture<T> {
319
    /// Utility function to create a new `ContextAwareFuture` from the
320
    /// active context.
321
    #[must_use = "futures do nothing unless you `.await` or poll them"]
322
    #[inline]
323
9
    pub fn new_from_active(inner: Instrumented<T>) -> ContextAwareFuture<T> {
324
9
        if let Some(ctx) = ActiveOriginContext::get() {
  Branch (324:16): [Folded - Ignored]
  Branch (324:16): [True: 2, False: 0]
  Branch (324:16): [True: 2, False: 0]
  Branch (324:16): [True: 2, False: 0]
  Branch (324:16): [True: 2, False: 0]
  Branch (324:16): [True: 1, False: 0]
  Branch (324:16): [Folded - Ignored]
325
9
            ContextAwareFuture::new(Some(ctx), inner)
326
        } else {
327
            // Useful to get tracing stack trace.
328
0
            tracing::error!("OriginContext must be set");
329
0
            panic!("OriginContext must be set");
330
        }
331
9
    }
332
333
    #[must_use = "futures do nothing unless you `.await` or poll them"]
334
    #[inline]
335
1.80k
    pub(crate) fn new(context: Option<Arc<OriginContext>>, inner: Instrumented<T>) -> Self {
336
1.80k
        Self {
337
1.80k
            inner: ManuallyDrop::new(inner),
338
1.80k
            context,
339
1.80k
        }
340
1.80k
    }
341
}
342
343
impl<T: Future> Future for ContextAwareFuture<T> {
344
    type Output = T::Output;
345
346
    #[inline]
347
14.8k
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
348
14.8k
        let this = self.project();
349
14.8k
        let Some(ctx) = this.context.take() else {
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 22, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 115, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 32, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 6, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 54, False: 0]
  Branch (349:13): [True: 1.22k, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 28, False: 0]
  Branch (349:13): [Folded - Ignored]
  Branch (349:13): [True: 74, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 706, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 290, False: 0]
  Branch (349:13): [True: 67, False: 0]
  Branch (349:13): [True: 270, False: 0]
  Branch (349:13): [True: 13, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 15, False: 0]
  Branch (349:13): [True: 13, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 7, False: 0]
  Branch (349:13): [True: 13, False: 0]
  Branch (349:13): [True: 7, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 2.63k, False: 0]
  Branch (349:13): [True: 83, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 6, False: 0]
  Branch (349:13): [True: 32, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 31, False: 0]
  Branch (349:13): [True: 3.26k, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 6, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 6, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1.03k, False: 0]
  Branch (349:13): [True: 6, False: 0]
  Branch (349:13): [True: 19, False: 0]
  Branch (349:13): [True: 15, False: 0]
  Branch (349:13): [True: 19, False: 0]
  Branch (349:13): [True: 11, False: 0]
  Branch (349:13): [True: 10, False: 0]
  Branch (349:13): [True: 23, False: 0]
  Branch (349:13): [True: 15, False: 0]
  Branch (349:13): [True: 13, False: 0]
  Branch (349:13): [True: 28, False: 0]
  Branch (349:13): [True: 20, False: 0]
  Branch (349:13): [True: 19, False: 0]
  Branch (349:13): [True: 10, False: 0]
  Branch (349:13): [True: 28, False: 0]
  Branch (349:13): [True: 22, False: 0]
  Branch (349:13): [True: 16, False: 0]
  Branch (349:13): [True: 34, False: 0]
  Branch (349:13): [True: 21, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 26, False: 0]
  Branch (349:13): [True: 1.02k, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 16, False: 0]
  Branch (349:13): [True: 16, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 40, False: 0]
  Branch (349:13): [True: 43, False: 0]
  Branch (349:13): [True: 40, False: 0]
  Branch (349:13): [True: 42, False: 0]
  Branch (349:13): [True: 47, False: 0]
  Branch (349:13): [True: 15, False: 0]
  Branch (349:13): [True: 13, False: 0]
  Branch (349:13): [True: 16, False: 0]
  Branch (349:13): [True: 17, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 18, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 9, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 9, False: 0]
  Branch (349:13): [True: 8, False: 0]
  Branch (349:13): [True: 12, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 24, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 10, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [Folded - Ignored]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 12, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 6, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 6, False: 0]
  Branch (349:13): [True: 7, False: 0]
  Branch (349:13): [True: 9, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 45, False: 0]
  Branch (349:13): [True: 75, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 46, False: 0]
  Branch (349:13): [True: 76, False: 0]
  Branch (349:13): [True: 6, False: 0]
  Branch (349:13): [True: 6, False: 0]
  Branch (349:13): [True: 42, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 35, False: 0]
  Branch (349:13): [True: 16, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 44, False: 0]
  Branch (349:13): [True: 28, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 10, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 17, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 51, False: 0]
  Branch (349:13): [True: 52, False: 0]
  Branch (349:13): [True: 12, False: 0]
  Branch (349:13): [True: 12, False: 0]
  Branch (349:13): [True: 58, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 26, False: 0]
  Branch (349:13): [True: 7, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 51, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 24, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 24, False: 0]
  Branch (349:13): [True: 24, False: 0]
  Branch (349:13): [True: 24, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 24, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 0, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 6, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 73, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 502, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 993, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 6, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 6, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 5, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 3, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 4, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 2, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
  Branch (349:13): [True: 1, False: 0]
350
            // Useful to get tracing stack trace.
351
0
            tracing::error!("Expected context to be set");
352
0
            panic!("Expected context to be set");
353
        };
354
14.8k
        let enter = ctx.enter();
355
14.8k
        // Since `inner` is only moved when the future itself is dropped, `inner` will
356
14.8k
        // never move, so this should be safe.
357
14.8k
        // see: https://docs.rs/tracing/0.1.40/src/tracing/instrument.rs.html#297
358
14.8k
        let inner = unsafe { this.inner.map_unchecked_mut(|v| &mut **v) };
359
14.8k
        let result = inner.poll(cx);
360
14.8k
        assert!(
361
14.8k
            this.context.replace(enter.release()).is_none(),
362
0
            "Expected context to be unset"
363
        );
364
14.8k
        result
365
14.8k
    }
366
}