1#![cfg_attr(feature="experimental-auto-traits", feature(optin_builtin_traits))]
2#![cfg_attr(not(feature="std"), no_std)]
3#[cfg(feature="std")]
8use std as core;
9
10use core::sync::atomic::*;
11use core::num::*;
12
13#[cfg(feature="experimental-auto-traits")]
14macro_rules! maybe_auto_trait {
15 ($doctext:literal pub unsafe trait $traitname:ident: $deps:ident {}) => {
16 #[doc=$doctext]
18 pub unsafe auto trait $traitname {}
19 }
20}
21
22#[cfg(not(feature="experimental-auto-traits"))]
23macro_rules! maybe_auto_trait {
24 ($doctext:literal pub unsafe trait $traitname:ident: $deps:ident {}) => {
25 #[doc=$doctext]
26 pub unsafe trait $traitname: $deps {}
27 }
28}
29
30maybe_auto_trait! {
31"Types which can be transferred across process boundary.
32
33An example of non-`ProcSend` type would be any type that contains pointers to values in \
34a process’ address space. Instead a `ProcSend` type would use indices which the \
35processes would know how to convert into their own address space.
36
37In general, for any type to implement `ProcSend`, it must be [`Send`], as threads \
38conceptually are the same as processes which share the same address space.
39
40Unlike [`Send`], `ProcSend` is not an auto-trait by default, because auto-traits are not stable. \
41Unless the `auto_traits` feature is enabled, it will be necessary to implement this \
42trait manually.
43
44Finally, currently `ProcSend` is only implemented for the built-in types which have \
45specified type layout and are ffi-safe. This is a conservative default as there is \
46no guarantee that the two interacting processes will be compiled with a same version \
47of Rust or are Rust at all."
48pub unsafe trait ProcSend: Send {}
49}
50
51maybe_auto_trait! {
52"Types for which it is safe to share references between processes.
53
54Much like [`ProcSend`] is a cross-process [`Send`], [`ProcSync`] is a cross-process [`Sync`].
55
56In general, for any type to implement `ProcSync`, it must be [`Sync`], as threads conceptually \
57are the same as processes which sahre the same address space.
58
59Unlike [`Sync`], `ProcSync` is not an auto-trait by default, because auto-traits are not stable. \
60Unless the `auto_traits` feature is enabled, it will be necessary to implement this \
61trait manually."
62pub unsafe trait ProcSync: Sync {}
63}
64
65macro_rules! implement_marker_for {
66 (unsafe impl $trait:ident for $($t:ty),*) => {
67 $(unsafe impl $trait for $t {})*
68 };
69 (unsafe impl !$trait:ident for $($t:ty),*) => {
70 $(unsafe impl !$trait for $t {})*
71 };
72}
73
74macro_rules! implement_marker_for_tuples {
75 (unsafe impl $trait:ident for) => { };
76 (unsafe impl $trait:ident for $hd:ident, $($tl:ident,)*) => {
77 unsafe impl<$hd: $trait, $($tl: $trait),*> $trait for ($hd, $($tl),*) {}
78 implement_marker_for_tuples! {
79 unsafe impl $trait for $($tl,)*
80 }
81 };
82}
83
84implement_marker_for! {
85 unsafe impl ProcSend for
86 u8, u16, u32, u64, u128, usize,
87 i8, i16, i32, i64, i128, isize,
88 f32, f64,
89 bool, char, str,
90 AtomicU8, AtomicU16, AtomicU32, AtomicU64, AtomicUsize,
91 AtomicI8, AtomicI16, AtomicI32, AtomicI64, AtomicIsize,
92 AtomicBool,
93 NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize,
94 NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize,
95 core::ffi::c_void
96}
97
98implement_marker_for_tuples! {
99 unsafe impl ProcSend for
100 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
101}
102
103unsafe impl<T: ProcSend> ProcSend for core::cell::RefCell<T> {}
104unsafe impl<T: ProcSend> ProcSend for core::cell::Cell<T> {}
105unsafe impl<T: ProcSend> ProcSend for core::cell::UnsafeCell<T> {}
106unsafe impl<T: ProcSend> ProcSend for core::mem::ManuallyDrop<T> {}
107
108#[cfg(feature="experimental-auto-traits")]
109impl<T> !ProcSend for *const T {}
110#[cfg(feature="experimental-auto-traits")]
111impl<T> !ProcSend for *mut T {}
112#[cfg(feature="experimental-auto-traits")]
113impl<T> !ProcSend for AtomicPtr<T> {}
114#[cfg(feature="experimental-auto-traits")]
115impl<T> !ProcSend for &T {}
116#[cfg(feature="experimental-auto-traits")]
117impl<T> !ProcSend for &mut T {}
118#[cfg(all(feature="experimental-auto-traits", feature="std"))]
119impl !ProcSend for std::net::TcpListener {}
120#[cfg(all(feature="experimental-auto-traits", feature="std"))]
121impl !ProcSend for std::net::TcpStream {}
122#[cfg(all(feature="experimental-auto-traits", feature="std"))]
123impl !ProcSend for std::net::UdpSocket {}
124#[cfg(all(feature="experimental-auto-traits", feature="std", unix))]
125impl !ProcSend for std::os::unix::net::UnixDatagram {}
126#[cfg(all(feature="experimental-auto-traits", feature="std", unix))]
127impl !ProcSend for std::os::unix::net::UnixListener {}
128#[cfg(all(feature="experimental-auto-traits", feature="std", unix))]
129impl !ProcSend for std::os::unix::net::UnixStream {}
130#[cfg(all(feature="experimental-auto-traits", feature="std"))]
131impl !ProcSend for std::fs::File {}
132#[cfg(all(feature="experimental-auto-traits", feature="std"))]
133impl !ProcSend for std::process::Child {}
134#[cfg(all(feature="experimental-auto-traits", feature="std"))]
135impl !ProcSend for std::process::ChildStderr {}
136#[cfg(all(feature="experimental-auto-traits", feature="std"))]
137impl !ProcSend for std::process::ChildStdin {}
138#[cfg(all(feature="experimental-auto-traits", feature="std"))]
139impl !ProcSend for std::process::ChildStdout {}
140#[cfg(all(feature="experimental-auto-traits", feature="std"))]
141impl !ProcSend for std::process::Stdio {}
142#[cfg(all(feature="experimental-auto-traits", feature="std"))]
143impl !ProcSend for std::thread::ThreadId {}
144
145
146implement_marker_for! {
147 unsafe impl ProcSync for
148 u8, u16, u32, u64, u128, usize,
149 i8, i16, i32, i64, i128, isize,
150 f32, f64,
151 bool, char, str,
152 AtomicU8, AtomicU16, AtomicU32, AtomicU64, AtomicUsize,
153 AtomicI8, AtomicI16, AtomicI32, AtomicI64, AtomicIsize,
154 AtomicBool,
155 NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize,
156 NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize,
157 core::ffi::c_void
158}
159
160implement_marker_for_tuples! {
161 unsafe impl ProcSync for
162 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
163}
164
165unsafe impl<T: ProcSync> ProcSync for core::mem::ManuallyDrop<T> {}
166
167#[cfg(feature="experimental-auto-traits")]
168impl<T> !ProcSync for core::cell::Cell<T> {}
169#[cfg(feature="experimental-auto-traits")]
170impl<T> !ProcSync for core::cell::UnsafeCell<T> {}
171#[cfg(feature="experimental-auto-traits")]
172impl<T> !ProcSync for *const T {}
173#[cfg(feature="experimental-auto-traits")]
174impl<T> !ProcSync for *mut T {}
175#[cfg(feature="experimental-auto-traits")]
176impl<T> !ProcSync for AtomicPtr<T> {}
177#[cfg(feature="experimental-auto-traits")]
178impl<T> !ProcSync for core::ptr::NonNull<T> {}
179#[cfg(feature="experimental-auto-traits")]
180impl<T> !ProcSync for &T {}
181#[cfg(feature="experimental-auto-traits")]
182impl<T> !ProcSync for &mut T {}
183#[cfg(all(feature="experimental-auto-traits", feature="std"))]
184impl !ProcSync for std::net::TcpListener {}
185#[cfg(all(feature="experimental-auto-traits", feature="std"))]
186impl !ProcSync for std::net::TcpStream {}
187#[cfg(all(feature="experimental-auto-traits", feature="std"))]
188impl !ProcSync for std::net::UdpSocket {}
189#[cfg(all(feature="experimental-auto-traits", feature="std", unix))]
190impl !ProcSync for std::os::unix::net::UnixDatagram {}
191#[cfg(all(feature="experimental-auto-traits", feature="std", unix))]
192impl !ProcSync for std::os::unix::net::UnixListener {}
193#[cfg(all(feature="experimental-auto-traits", feature="std", unix))]
194impl !ProcSync for std::os::unix::net::UnixStream {}
195#[cfg(all(feature="experimental-auto-traits", feature="std"))]
196impl !ProcSync for std::fs::File {}
197#[cfg(all(feature="experimental-auto-traits", feature="std"))]
198impl !ProcSync for std::process::Child {}
199#[cfg(all(feature="experimental-auto-traits", feature="std"))]
200impl !ProcSync for std::process::ChildStderr {}
201#[cfg(all(feature="experimental-auto-traits", feature="std"))]
202impl !ProcSync for std::process::ChildStdin {}
203#[cfg(all(feature="experimental-auto-traits", feature="std"))]
204impl !ProcSync for std::process::ChildStdout {}
205#[cfg(all(feature="experimental-auto-traits", feature="std"))]
206impl !ProcSync for std::process::Stdio {}
207#[cfg(all(feature="experimental-auto-traits", feature="std"))]
208impl !ProcSync for std::thread::ThreadId {}