1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//! RAII guard for Mono thread attachment.
//!
//! Mono requires every thread that interacts with managed objects to register itself with the
//! runtime via `mono_thread_attach` before making any API calls, and to unregister via
//! `mono_thread_detach` before the thread exits. Failing to detach leaks the thread's entry in
//! Mono's internal thread table and prevents the garbage collector from reclaiming associated
//! resources.
//!
//! [`MonoThreadGuard`] encapsulates this lifecycle: constructing it attaches the current thread,
//! and dropping it detaches it. Because [`MonoThreadGuard`] is [`!Send`][std::marker::Send], the
//! compiler guarantees that drop happens on the same thread as construction, which is required by
//! Mono's attach/detach contract.
use c_void;
use PhantomData;
use ;
/// A RAII guard that keeps the current thread attached to the Mono runtime.
///
/// Constructing this guard calls `mono_thread_attach`, registering the thread with the Mono GC
/// and enabling the use of all Mono handle types. Dropping it calls `mono_thread_detach`,
/// releasing the thread's entry in the runtime.
///
/// # `!Send + !Sync`
///
/// This type deliberately does not implement [`Send`] or [`Sync`]. `mono_thread_detach` must be
/// called from the same operating-system thread that called `mono_thread_attach`. If the guard
/// were moved to another thread and dropped there, it would detach the wrong thread, leaving the
/// original thread permanently registered and causing the detaching thread to corrupt Mono's
/// internal bookkeeping.
///
/// The `!Send` bound also creates a natural pairing with the handle types in this crate: since
/// all Mono handles are `!Send + !Sync`, they cannot escape the thread on which they were
/// obtained, and that thread is guaranteed to hold a live guard.
///
/// # Panics
///
/// The `Drop` implementation does not panic. If the Mono API is unavailable at drop time
/// (which cannot happen under normal use since the guard can only be constructed after a
/// successful [`init`](crate::init)), a warning is emitted via [`tracing`] and the detach is
/// skipped.