firestorm_enabled/internal.rs
1use crate::*;
2pub use firestorm_core::{EventData, Start};
3use std::marker::PhantomData;
4
5// See also 6cb371a0-d6f0-48be-87d2-8d824b82e0e7
6// This is a hack to impl !Send for SpanGuard.
7// The reason we want to do this is to prevent
8// the SpanGuard to be sent to another thread
9// where it can pop a scope that wasn't pushed
10// into the same collection (which would eventually
11// result in a panic or some very misleading data)
12// Generally the library doesn't force you to not do this -
13// you can still go out of your way to create a problem. But,
14// this prevents an easy mistake profiling an `async fn`. It is
15// still possible to profile an async fn, but the future won't impl
16// Send, which prevents this problem.
17struct Unsend(PhantomData<*const ()>);
18impl Unsend {
19 #[inline(always)]
20 fn new() -> Self {
21 Self(PhantomData)
22 }
23}
24unsafe impl Sync for Unsend {}
25pub struct SpanGuard(Unsend);
26impl SpanGuard {
27 #[inline(always)]
28 pub fn new() -> Self {
29 Self(Unsend::new())
30 }
31}
32
33impl Drop for SpanGuard {
34 #[inline(always)]
35 fn drop(&mut self) {
36 crate::end();
37 }
38}
39
40pub fn start(data: EventData) {
41 with_events(|events| {
42 let event = Event {
43 time: TimeSample::now(),
44 data,
45 };
46 events.push(event);
47 });
48}