borrowscope_runtime/tracker/
concurrency.rs

1//! Concurrency tracking: threads, channels, lock guards
2
3use super::TRACKER;
4
5pub fn track_thread_spawn<T>(
6    #[cfg_attr(not(feature = "track"), allow(unused_variables))] thread_id: &str,
7    #[cfg_attr(not(feature = "track"), allow(unused_variables))] location: &str,
8    handle: std::thread::JoinHandle<T>,
9) -> std::thread::JoinHandle<T> {
10    #[cfg(feature = "track")]
11    {
12        let mut tracker = TRACKER.lock();
13        tracker.record_thread_spawn(thread_id, location);
14    }
15    handle
16}
17
18/// Track thread join
19#[inline(always)]
20pub fn track_thread_join<T>(
21    #[cfg_attr(not(feature = "track"), allow(unused_variables))] thread_id: &str,
22    #[cfg_attr(not(feature = "track"), allow(unused_variables))] location: &str,
23    result: std::thread::Result<T>,
24) -> std::thread::Result<T> {
25    #[cfg(feature = "track")]
26    {
27        let mut tracker = TRACKER.lock();
28        tracker.record_thread_join(thread_id, location);
29    }
30    result
31}
32
33/// Track channel creation (returns both sender and receiver)
34#[inline(always)]
35pub fn track_channel<T>(
36    #[cfg_attr(not(feature = "track"), allow(unused_variables))] channel_id: &str,
37    #[cfg_attr(not(feature = "track"), allow(unused_variables))] location: &str,
38    sender: std::sync::mpsc::Sender<T>,
39    receiver: std::sync::mpsc::Receiver<T>,
40) -> (std::sync::mpsc::Sender<T>, std::sync::mpsc::Receiver<T>) {
41    #[cfg(feature = "track")]
42    {
43        let mut tracker = TRACKER.lock();
44        tracker.record_channel_sender_new(&format!("{}_tx", channel_id), channel_id, location);
45        tracker.record_channel_receiver_new(&format!("{}_rx", channel_id), channel_id, location);
46    }
47    (sender, receiver)
48}
49
50/// Track channel send
51#[inline(always)]
52pub fn track_channel_send<T>(
53    #[cfg_attr(not(feature = "track"), allow(unused_variables))] sender_id: &str,
54    #[cfg_attr(not(feature = "track"), allow(unused_variables))] location: &str,
55    result: Result<(), std::sync::mpsc::SendError<T>>,
56) -> Result<(), std::sync::mpsc::SendError<T>> {
57    #[cfg(feature = "track")]
58    {
59        let mut tracker = TRACKER.lock();
60        tracker.record_channel_send(sender_id, location);
61    }
62    result
63}
64
65/// Track channel receive
66#[inline(always)]
67pub fn track_channel_recv<T>(
68    #[cfg_attr(not(feature = "track"), allow(unused_variables))] receiver_id: &str,
69    #[cfg_attr(not(feature = "track"), allow(unused_variables))] location: &str,
70    result: Result<T, std::sync::mpsc::RecvError>,
71) -> Result<T, std::sync::mpsc::RecvError> {
72    #[cfg(feature = "track")]
73    {
74        let success = result.is_ok();
75        let mut tracker = TRACKER.lock();
76        tracker.record_channel_recv(receiver_id, success, location);
77    }
78    result
79}
80
81/// Track channel try_recv
82#[inline(always)]
83pub fn track_channel_try_recv<T>(
84    #[cfg_attr(not(feature = "track"), allow(unused_variables))] receiver_id: &str,
85    #[cfg_attr(not(feature = "track"), allow(unused_variables))] location: &str,
86    result: Result<T, std::sync::mpsc::TryRecvError>,
87) -> Result<T, std::sync::mpsc::TryRecvError> {
88    #[cfg(feature = "track")]
89    {
90        let success = result.is_ok();
91        let mut tracker = TRACKER.lock();
92        tracker.record_channel_recv(receiver_id, success, location);
93    }
94    result
95}
96