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
88
89
90
91
92
93
94
95
//! [`ThreadLocalToken`] — a brand confined to its originating thread.
use fmt;
use PhantomData;
use crateSealed;
use crate;
/// A brand owner that is statically pinned to one thread.
///
/// `ThreadLocalToken` provides the same read/write permit interface as
/// [`ExclusiveToken`](crate::ExclusiveToken)—a `&` borrow is a [`ReadPermit`]
/// and a `&mut` borrow is a [`WritePermit`]—but it deliberately implements
/// neither [`Send`] nor [`Sync`] (it carries a `*const ()` phantom). The whole
/// capability, and therefore every cell it governs, is consequently un-sendable:
/// the compiler rejects any attempt to move the access right to another thread.
///
/// Use this brand for allocator metadata that must never leave its owning
/// thread—free lists, bump cursors, and other structures whose soundness rests
/// on single-thread confinement rather than synchronisation.
// SAFETY: identical reasoning to `&ExclusiveToken` / `&mut ExclusiveToken`—the
// unique owning token mediates brand-wide XOR through the borrow checker. The
// extra `!Send` posture only narrows where the capability may be used.
unsafe
unsafe
unsafe
/// Open a thread-confined branding scope.
///
/// The token handed to `f` is `!Send`, so neither it nor any cell it governs
/// can be moved to another thread—confinement is proven at compile time.
///
/// # Examples
///
/// ```
/// use melinoe::{sync::thread_local_scope, MelinoeCell};
///
/// let total = thread_local_scope(|mut token| {
/// let counter = MelinoeCell::new(0_usize);
/// for _ in 0..5 {
/// *counter.borrow_mut(&mut token) += 1;
/// }
/// *counter.borrow(&token)
/// });
/// assert_eq!(total, 5);
/// ```
///
/// The token is `!Send`, so the compiler forbids moving the capability—or any
/// cell governed by it—onto another thread:
///
/// ```compile_fail
/// use melinoe::sync::thread_local_scope;
/// fn require_send<T: Send>(_: &T) {}
/// thread_local_scope(|token| {
/// require_send(&token); // ERROR: `ThreadLocalToken` is not `Send`
/// });
/// ```