qcell/qcell.rs
1use core::cell::UnsafeCell;
2use core::marker::PhantomPinned;
3use core::pin::Pin;
4use core::sync::atomic::{AtomicUsize, Ordering};
5
6#[cfg(feature = "alloc")]
7use alloc::boxed::Box;
8
9// Ensure the alignment is 2 so we can use odd-numbered IDs for those
10// created via `QCellOwnerSeq`.
11#[repr(align(2))]
12#[derive(Clone, Copy)]
13struct OwnerIDTarget {
14 _data: u16,
15}
16
17const MAGIC_OWNER_ID_TARGET: OwnerIDTarget = OwnerIDTarget { _data: 0xCE11 };
18
19#[cold]
20#[inline(never)]
21fn bad_owner_panic() -> ! {
22 panic!("QCell accessed with incorrect owner");
23}
24
25macro_rules! owner_check {
26 ($owner:expr $(, $qcell:expr)+) => {
27 $(
28 if $qcell.owner.0 != $owner.id().0 {
29 bad_owner_panic();
30 }
31 )+
32 }
33}
34
35#[cold]
36#[inline(never)]
37fn not_distinct_panic() -> ! {
38 panic!("Illegal to borrow same QCell twice with rw2() or rw3()");
39}
40
41macro_rules! distinct_check {
42 ($qc1:expr, $qc2:expr) => {{
43 let qc1 = $qc1 as *const _ as *const () as usize;
44 let qc2 = $qc2 as *const _ as *const () as usize;
45 if qc1 == qc2 {
46 not_distinct_panic();
47 }
48 }};
49 ($qc1:expr, $qc2:expr, $qc3:expr) => {{
50 let qc1 = $qc1 as *const _ as *const () as usize;
51 let qc2 = $qc2 as *const _ as *const () as usize;
52 let qc3 = $qc3 as *const _ as *const () as usize;
53 if qc1 == qc2 || qc2 == qc3 || qc3 == qc1 {
54 not_distinct_panic();
55 }
56 }};
57}
58
59/// Internal ID associated with a [`QCell`] owner.
60///
61/// The only purpose of this is to create [`QCell`] instances without
62/// requiring a borrow on the owner. A [`QCellOwnerID`] can be passed
63/// to any code that needs to create [`QCell`] instances. However to
64/// access those [`QCell`] instances after creation will still require
65/// a borrow on the original owner. Create a [`QCellOwnerID`] from an
66/// owner using `owner.into()` or `owner.id()`.
67///
68/// # Safety
69///
70/// Whilst the existence of this type does mean that an ID can exist
71/// longer than than the owner, all that allows is new [`QCell`]
72/// instances to be created after the owner has gone. But [`QCell`]
73/// instances can outlive the owner in any case, so this makes no
74/// difference to safety.
75#[derive(Clone, Copy, PartialEq, Eq, Hash)]
76pub struct QCellOwnerID(usize);
77
78impl QCellOwnerID {
79 /// Create a new cell owned by this owner-ID. See also
80 /// [`QCell::new`].
81 ///
82 /// [`QCell::new`]: struct.QCell.html
83 pub fn cell<T>(self, value: T) -> QCell<T> {
84 QCell {
85 value: UnsafeCell::new(value),
86 owner: self,
87 }
88 }
89}
90
91#[cfg(feature = "alloc")]
92impl From<&QCellOwner> for QCellOwnerID {
93 fn from(owner: &QCellOwner) -> Self {
94 owner.id()
95 }
96}
97
98impl From<&QCellOwnerSeq> for QCellOwnerID {
99 fn from(owner: &QCellOwnerSeq) -> Self {
100 owner.id()
101 }
102}
103
104impl From<Pin<&QCellOwnerPinned>> for QCellOwnerID {
105 fn from(owner: Pin<&QCellOwnerPinned>) -> Self {
106 owner.id()
107 }
108}
109
110/// Cell whose contents is owned (for borrowing purposes) by a
111/// [`QCellOwner`], a [`QCellOwnerSeq`] or a [`QCellOwnerPinned`].
112///
113/// To borrow from this cell, use the borrowing calls on the owner
114/// instance that was used to create it. For [`QCellOwner`], there
115/// are also convenience methods [`QCell::ro`] and [`QCell::rw`]. See
116/// also [crate documentation](index.html).
117///
118/// [`QCellOwner`]: struct.QCellOwner.html
119/// [`QCell::ro`]: struct.QCell.html#method.ro
120/// [`QCell::rw`]: struct.QCell.html#method.rw
121pub struct QCell<T: ?Sized> {
122 owner: QCellOwnerID,
123 value: UnsafeCell<T>,
124}
125
126// QCell already automatically implements Send, but not Sync.
127// We can add this implementation though, since it's fine to
128// send a &QCell to another thread, and even mutably borrow the value
129// there, as long as T is Send and Sync.
130//
131// The reason why QCell<T>'s impl of Sync requires T: Send + Sync
132// instead of just T: Sync is that QCell provides interior mutability.
133// If you send a &QCell<T> (and its owner) to a different thread, you
134// can call .rw() to get a &mut T, and use std::mem::swap() to move
135// the T, effectively sending the T to that other thread. That's not
136// allowed if T: !Send.
137//
138// Note that the bounds on T for QCell<T>'s impl of Sync are the same
139// as those of std::sync::RwLock<T>. That's not a coincidence.
140// The way these types let you access T concurrently is the same,
141// even though the locking mechanisms are different.
142unsafe impl<T: Send + Sync + ?Sized> Sync for QCell<T> {}
143
144impl<T> QCell<T> {
145 /// Create a new [`QCell`] owned for borrowing purposes by the
146 /// owner with the given [`QCellOwnerID`], or a type that can be
147 /// converted into a [`QCellOwnerID`], such as `&owner`. So calls
148 /// will typically take the form `QCell::new(&owner, value)` or
149 /// `QCell::new(owner_id, value)`.
150 #[inline]
151 pub fn new(id: impl Into<QCellOwnerID>, value: T) -> QCell<T> {
152 QCell {
153 value: UnsafeCell::new(value),
154 owner: id.into(),
155 }
156 }
157
158 /// Destroy the cell and return the contained value
159 ///
160 /// Safety: Since this consumes the cell, there can be no other
161 /// references to the cell or the data at this point.
162 #[inline]
163 pub fn into_inner(self) -> T {
164 self.value.into_inner()
165 }
166}
167
168#[cfg(feature = "alloc")]
169impl<T: ?Sized> QCell<T> {
170 /// Convenience method to borrow a cell immutably when the owner
171 /// is a [`QCellOwner`]. Equivalent to [`QCellOwner::ro`]. See
172 /// [`QCellOwnerSeq::ro`] or [`QCellOwnerPinned::ro`] to borrow
173 /// for other owner types.
174 #[inline]
175 pub fn ro<'a>(&'a self, owner: &'a QCellOwner) -> &'a T {
176 owner.ro(self)
177 }
178
179 /// Convenience method to borrow a cell mutably when the owner is
180 /// a [`QCellOwner`]. Equivalent to [`QCellOwner::rw`]. See
181 /// [`QCellOwnerSeq::rw`] or [`QCellOwnerPinned::rw`] to borrow
182 /// for other owner types.
183 #[inline]
184 pub fn rw<'a>(&'a self, owner: &'a mut QCellOwner) -> &'a mut T {
185 owner.rw(self)
186 }
187
188 /// Returns a mutable reference to the underlying data
189 ///
190 /// Note that this is only useful at the beginning-of-life or
191 /// end-of-life of the cell when you have exclusive access to it.
192 /// Normally you'd use [`QCell::rw`] or [`QCellOwner::rw`] to get
193 /// a mutable reference to the contents of the cell.
194 ///
195 /// Safety: This call borrows `QCell` mutably which guarantees
196 /// that we possess the only reference. This means that there can
197 /// be no active borrows of other forms, even ones obtained using
198 /// an immutable reference.
199 #[inline]
200 pub fn get_mut(&mut self) -> &mut T {
201 self.value.get_mut()
202 }
203}
204
205/// Borrowing-owner of zero or more [`QCell`] instances.
206///
207/// The owner will have a temporally unique ID associated with it to
208/// detect use of the wrong owner to access a cell at runtime, which
209/// is a programming error. Temporally unique means that at any one
210/// time, only one owner will hold that ID. This type derives the
211/// owner ID from the address of an internal memory allocation which
212/// this owner holds until it is dropped, which ensures that the ID is
213/// temporally unique. The allocation is aligned to ensure that its
214/// ID cannot collide with those created using [`QCellOwnerSeq`].
215///
216/// In a `no_std` environment this requires the `alloc` feature
217/// because it allocates memory. For a `no_std` environment without
218/// `alloc`, consider using [`QCellOwnerSeq`] or [`QCellOwnerPinned`].
219///
220/// # Safety
221///
222/// This should successfully defend against all malicious and unsafe
223/// use. If not, please raise an issue. The same unique ID may later
224/// be allocated to someone else once you drop the returned owner, but
225/// this cannot be abused to cause unsafe access to cells because
226/// there will still be only one owner active at any one time with
227/// that ID. Also it cannot be used maliciously to access cells which
228/// don't belong to the new caller, because you also need a reference
229/// to the cells. So for example if you have a graph of cells that is
230/// only accessible through a private structure, then if someone else
231/// gets the same owner ID later, it makes no difference, because they
232/// have no way to get a reference to those cells. In any case, you
233/// are probably going to drop all those cells at the same time as
234/// dropping the owner, because they are no longer of any use without
235/// the owner ID.
236///
237/// See [crate documentation](index.html).
238#[cfg(feature = "alloc")]
239#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
240pub struct QCellOwner {
241 // `Box` should be enough to ensure that the address is unique and
242 // stable, but add `Pin` as a safeguard against any future
243 // optimisation of `Box`.
244 handle: Pin<Box<OwnerIDTarget>>,
245}
246
247#[cfg(feature = "alloc")]
248#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
249impl Default for QCellOwner {
250 fn default() -> Self {
251 QCellOwner::new()
252 }
253}
254
255#[cfg(feature = "alloc")]
256#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
257impl QCellOwner {
258 /// Create an owner that can be used for creating many [`QCell`]
259 /// instances.
260 #[inline]
261 pub fn new() -> Self {
262 let handle = Box::pin(MAGIC_OWNER_ID_TARGET);
263 Self { handle }
264 }
265
266 /// Get the internal owner ID. This may be used to create [`QCell`]
267 /// instances without needing a borrow on this structure, which is
268 /// useful if this structure is already borrowed.
269 #[inline]
270 pub fn id(&self) -> QCellOwnerID {
271 let raw_ptr: *const OwnerIDTarget = &*self.handle;
272 QCellOwnerID(raw_ptr as usize)
273 }
274
275 /// Create a new cell owned by this owner instance. See also
276 /// [`QCell::new`].
277 #[inline]
278 pub fn cell<T>(&self, value: T) -> QCell<T> {
279 let id: QCellOwnerID = self.into();
280 id.cell(value)
281 }
282
283 /// Borrow contents of a [`QCell`] immutably (read-only). Many
284 /// [`QCell`] instances can be borrowed immutably at the same time
285 /// from the same owner. Panics if the [`QCell`] is not owned by
286 /// this [`QCellOwner`].
287 #[inline]
288 pub fn ro<'a, T: ?Sized>(&'a self, qc: &'a QCell<T>) -> &'a T {
289 owner_check!(self, qc);
290 unsafe { &*qc.value.get() }
291 }
292
293 /// Borrow contents of a [`QCell`] mutably (read-write). Only one
294 /// [`QCell`] at a time can be borrowed from the owner using this
295 /// call. The returned reference must go out of scope before
296 /// another can be borrowed. Panics if the [`QCell`] is not owned
297 /// by this [`QCellOwner`].
298 #[inline]
299 pub fn rw<'a, T: ?Sized>(&'a mut self, qc: &'a QCell<T>) -> &'a mut T {
300 owner_check!(self, qc);
301 unsafe { &mut *qc.value.get() }
302 }
303
304 /// Borrow contents of two [`QCell`] instances mutably. Panics if
305 /// the two [`QCell`] instances point to the same memory. Panics
306 /// if either [`QCell`] is not owned by this [`QCellOwner`].
307 #[inline]
308 pub fn rw2<'a, T: ?Sized, U: ?Sized>(
309 &'a mut self,
310 qc1: &'a QCell<T>,
311 qc2: &'a QCell<U>,
312 ) -> (&'a mut T, &'a mut U) {
313 owner_check!(self, qc1, qc2);
314 distinct_check!(qc1, qc2);
315 unsafe { (&mut *qc1.value.get(), &mut *qc2.value.get()) }
316 }
317
318 /// Borrow contents of three [`QCell`] instances mutably. Panics
319 /// if any pair of [`QCell`] instances point to the same memory.
320 /// Panics if any [`QCell`] is not owned by this [`QCellOwner`].
321 #[inline]
322 pub fn rw3<'a, T: ?Sized, U: ?Sized, V: ?Sized>(
323 &'a mut self,
324 qc1: &'a QCell<T>,
325 qc2: &'a QCell<U>,
326 qc3: &'a QCell<V>,
327 ) -> (&'a mut T, &'a mut U, &'a mut V) {
328 owner_check!(self, qc1, qc2, qc3);
329 distinct_check!(qc1, qc2, qc3);
330 unsafe {
331 (
332 &mut *qc1.value.get(),
333 &mut *qc2.value.get(),
334 &mut *qc3.value.get(),
335 )
336 }
337 }
338}
339
340// Used to generate a unique QCellOwnerID number for each
341// QCellOwnerSeq. Start at index 1 and increment by 2 each time so
342// the number is always odd to ensure it will never conflict with the
343// address of a OwnerIDTarget.
344static FAST_QCELLOWNER_ID: AtomicUsize = AtomicUsize::new(1);
345
346/// Borrowing-owner of zero or more [`QCell`] instances, using an ID
347/// sequence.
348///
349/// The owner will have a unique(-ish) ID associated with it to detect
350/// use of the wrong owner to access a cell at runtime, which is a
351/// programming error. This type allocates the owner ID from a
352/// wrapping sequence sourced from a global atomic variable, so it is
353/// very fast to allocate.
354///
355/// # Safety
356///
357/// A malicious coder could cause an intentional ID collision, e.g. by
358/// creating 2^63 owners on a 64-bit build (or 2^31 on 32-bit, etc),
359/// which would cause the ID to wrap. This would allow that coder to
360/// cause undefined behaviour in their own code. So at a stretch this
361/// could allow a coder to hide unsound code from a safety review.
362/// Because of that the [`QCellOwnerSeq::new`] method is marked as
363/// `unsafe`. However it is not possible to use it unsafely by
364/// accident, only through making an intentional, determined and
365/// CPU-intensive effort to exploit it.
366///
367/// See [crate documentation](index.html).
368pub struct QCellOwnerSeq {
369 id: QCellOwnerID,
370}
371
372// Default implementation not possible, due to `unsafe`
373
374impl QCellOwnerSeq {
375 /// Create an owner that can be used for creating many [`QCell`]
376 /// instances.
377 ///
378 /// # Safety
379 ///
380 /// The contract with the caller is that the caller must not
381 /// intentionally create an owner-ID collision and exploit it to
382 /// create undefined behaviour. The caller could do this by
383 /// creating 2^63 more owners on a 64-bit build (or 2^31 on
384 /// 32-bit, etc), causing the ID to wrap, and then using two
385 /// owners that they know to have the same ID to access the same
386 /// memory mutably from two references at the same time. This is
387 /// totally impossible to do by accident, so any normal use of
388 /// this call will be 100% safe.
389 ///
390 /// To get unsound behaviour requires both an owner ID collision
391 /// (which might just about happen by accident in very unusual
392 /// situations), and then also intentionally using the wrong owner
393 /// to access a cell. Usually using the wrong owner to access a
394 /// cell would cause an immediate panic because it is a
395 /// programming error. It is extremely unlikely that there would
396 /// always be the same ID collision in testing, so this panic
397 /// would soon be fixed. Once it is fixed, there is absolutely no
398 /// way that even an accidental collision could cause any unsound
399 /// behaviour, because the bug has been eliminated, and the
400 /// correct owner is always used to access each cell.
401 #[inline]
402 pub unsafe fn new() -> Self {
403 // Must increment by 2 to ensure we never collide with an ID
404 // derived from the address of an `OwnerIDTarget`. Use
405 // `Relaxed` ordering because we don't care who gets which ID,
406 // just that they are different.
407 Self {
408 id: QCellOwnerID(FAST_QCELLOWNER_ID.fetch_add(2, Ordering::Relaxed)),
409 }
410 }
411
412 /// Get the internal owner ID. This may be used to create
413 /// [`QCell`] instances without needing a borrow on this
414 /// structure, which is useful if this structure is already
415 /// borrowed.
416 #[inline]
417 pub fn id(&self) -> QCellOwnerID {
418 self.id
419 }
420
421 /// Create a new cell owned by this owner instance. See also
422 /// [`QCell::new`].
423 ///
424 /// [`QCell::new`]: struct.QCell.html
425 #[inline]
426 pub fn cell<T>(&self, value: T) -> QCell<T> {
427 self.id.cell(value)
428 }
429
430 /// Borrow contents of a [`QCell`] immutably (read-only). Many
431 /// [`QCell`] instances can be borrowed immutably at the same time
432 /// from the same owner. Panics if the [`QCell`] is not owned by
433 /// this [`QCellOwnerSeq`].
434 #[inline]
435 pub fn ro<'a, T: ?Sized>(&'a self, qc: &'a QCell<T>) -> &'a T {
436 owner_check!(self, qc);
437 unsafe { &*qc.value.get() }
438 }
439
440 /// Borrow contents of a [`QCell`] mutably (read-write). Only one
441 /// [`QCell`] at a time can be borrowed from the owner using this
442 /// call. The returned reference must go out of scope before
443 /// another can be borrowed. Panics if the [`QCell`] is not owned
444 /// by this [`QCellOwnerSeq`].
445 #[inline]
446 pub fn rw<'a, T: ?Sized>(&'a mut self, qc: &'a QCell<T>) -> &'a mut T {
447 owner_check!(self, qc);
448 unsafe { &mut *qc.value.get() }
449 }
450
451 /// Borrow contents of two [`QCell`] instances mutably. Panics if
452 /// the two [`QCell`] instances point to the same memory. Panics
453 /// if either [`QCell`] is not owned by this [`QCellOwnerSeq`].
454 #[inline]
455 pub fn rw2<'a, T: ?Sized, U: ?Sized>(
456 &'a mut self,
457 qc1: &'a QCell<T>,
458 qc2: &'a QCell<U>,
459 ) -> (&'a mut T, &'a mut U) {
460 owner_check!(self, qc1, qc2);
461 distinct_check!(qc1, qc2);
462 unsafe { (&mut *qc1.value.get(), &mut *qc2.value.get()) }
463 }
464
465 /// Borrow contents of three [`QCell`] instances mutably. Panics
466 /// if any pair of [`QCell`] instances point to the same memory.
467 /// Panics if any [`QCell`] is not owned by this
468 /// [`QCellOwnerSeq`].
469 #[inline]
470 pub fn rw3<'a, T: ?Sized, U: ?Sized, V: ?Sized>(
471 &'a mut self,
472 qc1: &'a QCell<T>,
473 qc2: &'a QCell<U>,
474 qc3: &'a QCell<V>,
475 ) -> (&'a mut T, &'a mut U, &'a mut V) {
476 owner_check!(self, qc1, qc2, qc3);
477 distinct_check!(qc1, qc2, qc3);
478 unsafe {
479 (
480 &mut *qc1.value.get(),
481 &mut *qc2.value.get(),
482 &mut *qc3.value.get(),
483 )
484 }
485 }
486}
487
488/// Borrowing-owner of zero or more [`QCell`] instances, based on a
489/// pinned struct
490///
491/// This type uses its own memory address to provide a unique owner
492/// ID, which requires no allocations and only 2 bytes of storage. So
493/// this is suitable for a `no_std` environment without an allocator.
494/// The owner can be created on the stack, or on the heap, as
495/// required. To ensure its memory address cannot change while cells
496/// exist that are owned by it, it requires itself to be pinned before
497/// any operation interacting with the ID is attempted.
498///
499/// There are many ways to safely pin a value, such as
500/// [`Box::pin`](https://doc.rust-lang.org/std/boxed/struct.Box.html#method.pin),
501/// [`pin-utils::pin_mut!`](https://docs.rs/pin-utils/latest/pin_utils/macro.pin_mut.html),
502/// [`tokio::pin!`](https://docs.rs/tokio/latest/tokio/macro.pin.html),
503/// or the [`pin-project`](https://github.com/taiki-e/pin-project)
504/// crate.
505///
506/// The following example uses the `pin_mut!` macro from the
507/// `pin-utils` crate:
508///
509/// ```
510/// use pin_utils::pin_mut;
511/// use qcell::{QCell, QCellOwnerPinned};
512///# use std::rc::Rc;
513///# use std::pin::Pin;
514/// let mut owner = QCellOwnerPinned::new();
515/// pin_mut!(owner);
516/// let item = Rc::new(owner.as_ref().cell(Vec::<u8>::new()));
517/// owner.as_mut().rw(&item).push(1);
518/// test(owner, &item);
519///
520/// fn test(owner: Pin<&mut QCellOwnerPinned>, item: &Rc<QCell<Vec<u8>>>) {
521/// owner.rw(&item).push(2);
522/// }
523/// ```
524///
525/// This example incorporates the [`QCellOwnerPinned`] into a larger
526/// structure kept on the stack, and accesses it using the
527/// [`pin-project`](https://github.com/taiki-e/pin-project) crate:
528///
529/// ```
530/// use crate::qcell::{QCell, QCellOwnerPinned};
531/// use pin_project::pin_project;
532/// use pin_utils::pin_mut;
533///# use std::pin::Pin;
534///# use std::rc::Rc;
535///
536/// #[pin_project]
537/// struct MyStruct {
538/// _misc: usize, // Unpinned value
539/// #[pin]
540/// owner: QCellOwnerPinned,
541/// }
542///
543/// let mystruct = MyStruct {
544/// _misc: 0,
545/// owner: QCellOwnerPinned::new(),
546/// };
547///
548/// pin_mut!(mystruct);
549///
550/// let item = Rc::new(
551/// mystruct.as_mut().project().owner.as_ref().cell(Vec::<u8>::new())
552/// );
553/// mystruct.as_mut().project().owner.rw(&item).push(1);
554/// test(mystruct.as_mut().project().owner, &item);
555///
556/// fn test(owner: Pin<&mut QCellOwnerPinned>, item: &Rc<QCell<Vec<u8>>>) {
557/// owner.rw(&item).push(2);
558/// }
559/// ```
560///
561/// # Safety
562///
563/// After the owner is pinned, its address is used as a temporally
564/// unique ID. This detects use of the wrong owner to access a cell
565/// at runtime, which is a programming error.
566///
567/// Note that even without `Pin`, this would still be sound, because
568/// there would still be only one owner valid at any one time with the
569/// same ID, because two owners cannot occupy the same memory.
570/// However `Pin` is useful because it helps the coder avoid
571/// accidentally moving an owner from one address to another without
572/// realizing it, and causing panics due to the changed owner ID.
573///
574/// The ID generated from this type cannot clash with IDs generated by
575/// [`QCellOwner`] (which is also based on the addresses of occupied
576/// memory, but always on the heap), or [`QCellOwnerSeq`] (which only
577/// allocates odd IDs, which cannot clash with addresses from this
578/// type which always have an alignment of 2). So this should
579/// successfully defend against all malicious and unsafe use. If not,
580/// please raise an issue.
581///
582/// The same unique ID may later be allocated to someone else once you
583/// drop the returned owner, but this cannot be abused to cause unsafe
584/// access to cells because there will still be only one owner active
585/// at any one time with that ID. Also it cannot be used maliciously
586/// to access cells which don't belong to the new caller, because you
587/// also need a reference to the cells. So for example if you have a
588/// graph of cells that is only accessible through a private
589/// structure, then someone else getting the same owner ID makes no
590/// difference, because they have no way to get a reference to those
591/// cells. In any case, you are probably going to drop all those
592/// cells at the same time as dropping the owner, because they are no
593/// longer of any use without the owner ID.
594///
595/// [`QCellOwner`]: struct.QCellOwner.html
596pub struct QCellOwnerPinned {
597 target: OwnerIDTarget,
598 // ensure this type is !Unpin
599 _marker: PhantomPinned,
600}
601
602impl Default for QCellOwnerPinned {
603 fn default() -> Self {
604 QCellOwnerPinned::new()
605 }
606}
607
608impl QCellOwnerPinned {
609 /// Create an owner that can be used for creating many [`QCell`]
610 /// instances.
611 #[inline]
612 pub fn new() -> Self {
613 Self {
614 target: MAGIC_OWNER_ID_TARGET,
615 _marker: PhantomPinned,
616 }
617 }
618
619 /// Get the internal owner ID. This may be used to create
620 /// [`QCell`] instances without needing a borrow on this
621 /// structure, which is useful if this structure is already
622 /// borrowed.
623 ///
624 /// Requires this owner to be pinned before use.
625 pub fn id(self: Pin<&Self>) -> QCellOwnerID {
626 // Pin guarantees that our address will not change until we
627 // are dropped, so we can use it as a unique ID.
628 let raw_ptr: *const OwnerIDTarget = &self.target;
629 QCellOwnerID(raw_ptr as usize)
630 }
631
632 /// Create a new cell owned by this owner instance.
633 ///
634 /// Requires this owner to be pinned before use.
635 #[inline]
636 pub fn cell<T>(self: Pin<&Self>, value: T) -> QCell<T> {
637 let id: QCellOwnerID = self.into();
638 id.cell(value)
639 }
640
641 /// Borrow contents of a [`QCell`] immutably (read-only). Many
642 /// [`QCell`] instances can be borrowed immutably at the same time
643 /// from the same owner. Panics if the [`QCell`] is not owned by
644 /// this [`QCellOwnerPinned`].
645 ///
646 /// Requires this owner to be pinned before use.
647 #[inline]
648 pub fn ro<'a, T: ?Sized>(self: Pin<&'a Self>, qc: &'a QCell<T>) -> &'a T {
649 owner_check!(self, qc);
650 unsafe { &*qc.value.get() }
651 }
652
653 /// Borrow contents of a [`QCell`] mutably (read-write). Only one
654 /// [`QCell`] at a time can be borrowed from the owner using this
655 /// call. The returned reference must go out of scope before
656 /// another can be borrowed. Panics if the [`QCell`] is not owned
657 /// by this [`QCellOwnerPinned`].
658 ///
659 /// Requires this owner to be pinned before use.
660 #[inline]
661 #[allow(clippy::mut_from_ref)]
662 pub fn rw<'a, T: ?Sized>(self: Pin<&'a mut Self>, qc: &'a QCell<T>) -> &'a mut T {
663 owner_check!(self.as_ref(), qc);
664 unsafe { &mut *qc.value.get() }
665 }
666
667 /// Borrow contents of two [`QCell`] instances mutably. Panics if
668 /// the two [`QCell`] instances point to the same memory. Panics
669 /// if either [`QCell`] is not owned by this [`QCellOwnerPinned`].
670 ///
671 /// Requires this owner to be pinned before use.
672 #[inline]
673 pub fn rw2<'a, T: ?Sized, U: ?Sized>(
674 self: Pin<&'a mut Self>,
675 qc1: &'a QCell<T>,
676 qc2: &'a QCell<U>,
677 ) -> (&'a mut T, &'a mut U) {
678 owner_check!(self.as_ref(), qc1, qc2);
679 distinct_check!(qc1, qc2);
680 unsafe { (&mut *qc1.value.get(), &mut *qc2.value.get()) }
681 }
682
683 /// Borrow contents of three [`QCell`] instances mutably. Panics
684 /// if any pair of [`QCell`] instances point to the same memory.
685 /// Panics if any [`QCell`] is not owned by this
686 /// [`QCellOwnerPinned`].
687 ///
688 /// Requires this owner to be pinned before use.
689 #[inline]
690 pub fn rw3<'a, T: ?Sized, U: ?Sized, V: ?Sized>(
691 self: Pin<&'a mut Self>,
692 qc1: &'a QCell<T>,
693 qc2: &'a QCell<U>,
694 qc3: &'a QCell<V>,
695 ) -> (&'a mut T, &'a mut U, &'a mut V) {
696 owner_check!(self.as_ref(), qc1, qc2, qc3);
697 distinct_check!(qc1, qc2, qc3);
698 unsafe {
699 (
700 &mut *qc1.value.get(),
701 &mut *qc2.value.get(),
702 &mut *qc3.value.get(),
703 )
704 }
705 }
706}
707
708#[cfg(test)]
709mod tests {
710 use core::pin::Pin;
711
712 use pin_utils::pin_mut;
713
714 use super::{QCell, QCellOwnerPinned, QCellOwnerSeq};
715
716 #[test]
717 fn qcell_pinned() {
718 let owner = QCellOwnerPinned::new();
719 pin_mut!(owner);
720 let c1 = owner.as_ref().cell(100u32);
721 let c2 = owner.as_ref().cell(200u32);
722 (*owner.as_mut().rw(&c1)) += 1;
723 (*owner.as_mut().rw(&c2)) += 2;
724 let c1ref = owner.as_ref().ro(&c1);
725 let c2ref = owner.as_ref().ro(&c2);
726 let total = *c1ref + *c2ref;
727 assert_eq!(total, 303);
728 }
729
730 #[test]
731 fn qcell_fast_ids_pinned() {
732 let owner1 = QCellOwnerPinned::new();
733 pin_mut!(owner1);
734 let id1 = owner1.as_ref().id();
735 let owner2 = unsafe { QCellOwnerSeq::new() };
736 let id2 = owner2.id;
737 assert_ne!(id1.0, id2.0, "Expected ID 1/2 to be different");
738 let owner3 = unsafe { QCellOwnerSeq::new() };
739 let id3 = owner3.id;
740 assert_ne!(id2.0, id3.0, "Expected ID 2/3 to be different");
741 drop(owner2);
742 drop(owner3);
743 let owner4 = QCellOwnerPinned::new();
744 pin_mut!(owner4);
745 let id4 = owner4.as_ref().id();
746 assert_ne!(id1.0, id4.0, "Expected ID 1/4 to be different");
747 assert_ne!(id2.0, id4.0, "Expected ID 2/4 to be different");
748 assert_ne!(id3.0, id4.0, "Expected ID 3/4 to be different");
749 }
750
751 #[test]
752 fn qcell_sep_ids_pinned() {
753 let owner1 = QCellOwnerPinned::new();
754 let owner2 = QCellOwnerPinned::new();
755 pin_mut!(owner1);
756 pin_mut!(owner2);
757 let id1 = owner1.as_ref().id();
758 let id2 = owner2.as_ref().id();
759 let c11 = id1.cell(1u32);
760 let c12 = id2.cell(2u32);
761 let c21 = owner1.as_ref().cell(4u32);
762 let c22 = owner2.as_ref().cell(8u32);
763 assert_eq!(
764 15,
765 owner1.as_ref().ro(&c11)
766 + owner2.as_ref().ro(&c12)
767 + owner1.as_ref().ro(&c21)
768 + owner2.as_ref().ro(&c22)
769 );
770 }
771
772 #[test]
773 fn qcell_unsized_pinned() {
774 let owner = QCellOwnerPinned::new();
775 struct Squares(u32);
776 struct Integers(u64);
777 trait Series {
778 fn step(&mut self);
779 fn value(&self) -> u64;
780 }
781 impl Series for Squares {
782 fn step(&mut self) {
783 self.0 += 1;
784 }
785 fn value(&self) -> u64 {
786 (self.0 as u64) * (self.0 as u64)
787 }
788 }
789 impl Series for Integers {
790 fn step(&mut self) {
791 self.0 += 1;
792 }
793 fn value(&self) -> u64 {
794 self.0
795 }
796 }
797 fn series(
798 init: u32,
799 is_squares: bool,
800 owner: Pin<&QCellOwnerPinned>,
801 ) -> Box<QCell<dyn Series>> {
802 if is_squares {
803 Box::new(owner.cell(Squares(init)))
804 } else {
805 Box::new(owner.cell(Integers(init as u64)))
806 }
807 }
808
809 pin_mut!(owner);
810 let cell1 = series(4, false, owner.as_ref());
811 let cell2 = series(7, true, owner.as_ref());
812 let cell3 = series(3, true, owner.as_ref());
813 assert_eq!(owner.as_ref().ro(&cell1).value(), 4);
814 owner.as_mut().rw(&cell1).step();
815 assert_eq!(owner.as_ref().ro(&cell1).value(), 5);
816 assert_eq!(owner.as_ref().ro(&cell2).value(), 49);
817 owner.as_mut().rw(&cell2).step();
818 assert_eq!(owner.as_ref().ro(&cell2).value(), 64);
819 let (r1, r2, r3) = owner.as_mut().rw3(&cell1, &cell2, &cell3);
820 r1.step();
821 r2.step();
822 r3.step();
823 assert_eq!(owner.as_ref().ro(&cell1).value(), 6);
824 assert_eq!(owner.as_ref().ro(&cell2).value(), 81);
825 assert_eq!(owner.as_ref().ro(&cell3).value(), 16);
826 let (r1, r2) = owner.as_mut().rw2(&cell1, &cell2);
827 r1.step();
828 r2.step();
829 assert_eq!(owner.as_ref().ro(&cell1).value(), 7);
830 assert_eq!(owner.as_ref().ro(&cell2).value(), 100);
831 }
832}
833
834#[cfg(all(test, feature = "alloc"))]
835mod tests_with_alloc {
836 use super::{QCell, QCellOwner, QCellOwnerSeq};
837
838 #[test]
839 fn qcell() {
840 let mut owner = QCellOwner::new();
841 let c1 = QCell::new(&owner, 100u32);
842 let c2 = QCell::new(&owner, 200u32);
843 (*owner.rw(&c1)) += 1;
844 (*owner.rw(&c2)) += 2;
845 let c1ref = owner.ro(&c1);
846 let c2ref = owner.ro(&c2);
847 let total = *c1ref + *c2ref;
848 assert_eq!(total, 303);
849 }
850
851 #[test]
852 fn qcell_ids() {
853 let owner1 = QCellOwner::new();
854 let id1 = owner1.id();
855 let owner2 = QCellOwner::new();
856 let id2 = owner2.id();
857 assert_ne!(id1.0, id2.0, "Expected ID 1/2 to be different");
858 drop(owner2);
859 let owner3 = QCellOwner::new();
860 let id3 = owner3.id();
861 assert_ne!(id1.0, id3.0, "Expected ID 1/3 to be different");
862 drop(owner3);
863 drop(owner1);
864 let owner4 = QCellOwner::new();
865 let id4 = owner4.id();
866 let owner5 = QCellOwner::new();
867 let id5 = owner5.id();
868 assert_ne!(id4.0, id5.0, "Expected ID 4/5 to be different");
869 }
870
871 #[test]
872 fn qcell_fast_ids() {
873 let owner1 = QCellOwner::new();
874 let id1 = owner1.id();
875 let owner2 = unsafe { QCellOwnerSeq::new() };
876 let id2 = owner2.id();
877 assert_ne!(id1.0, id2.0, "Expected ID 1/2 to be different");
878 let owner3 = unsafe { QCellOwnerSeq::new() };
879 let id3 = owner3.id();
880 assert_ne!(id2.0, id3.0, "Expected ID 2/3 to be different");
881 drop(owner2);
882 drop(owner3);
883 let owner4 = QCellOwner::new();
884 let id4 = owner4.id();
885 assert_ne!(id1.0, id4.0, "Expected ID 1/4 to be different");
886 assert_ne!(id2.0, id4.0, "Expected ID 2/4 to be different");
887 assert_ne!(id3.0, id4.0, "Expected ID 3/4 to be different");
888 }
889
890 #[test]
891 fn qcell_sep_ids() {
892 let owner1 = QCellOwner::new();
893 let owner2 = QCellOwner::new();
894 let id1 = owner1.id();
895 let id2 = owner2.id();
896 let c11 = id1.cell(1u32);
897 let c12 = id2.cell(2u32);
898 let c21 = owner1.cell(4u32);
899 let c22 = owner2.cell(8u32);
900 assert_eq!(
901 15,
902 owner1.ro(&c11) + owner2.ro(&c12) + owner1.ro(&c21) + owner2.ro(&c22)
903 );
904 }
905
906 #[test]
907 fn qcell_get_mut() {
908 let owner = QCellOwner::new();
909 let mut cell = QCell::new(&owner, 100u32);
910 let mut_ref = cell.get_mut();
911 *mut_ref = 50;
912 let cell_ref = owner.ro(&cell);
913 assert_eq!(*cell_ref, 50);
914 }
915
916 #[test]
917 fn qcell_into_inner() {
918 let owner = QCellOwner::new();
919 let cell = QCell::new(&owner, 100u32);
920 assert_eq!(cell.into_inner(), 100);
921 }
922
923 #[test]
924 fn qcell_unsized() {
925 let mut owner = QCellOwner::new();
926 struct Squares(u32);
927 struct Integers(u64);
928 trait Series {
929 fn step(&mut self);
930 fn value(&self) -> u64;
931 }
932 impl Series for Squares {
933 fn step(&mut self) {
934 self.0 += 1;
935 }
936 fn value(&self) -> u64 {
937 (self.0 as u64) * (self.0 as u64)
938 }
939 }
940 impl Series for Integers {
941 fn step(&mut self) {
942 self.0 += 1;
943 }
944 fn value(&self) -> u64 {
945 self.0
946 }
947 }
948 fn series(init: u32, is_squares: bool, owner: &QCellOwner) -> Box<QCell<dyn Series>> {
949 if is_squares {
950 Box::new(QCell::new(owner, Squares(init)))
951 } else {
952 Box::new(QCell::new(owner, Integers(init as u64)))
953 }
954 }
955
956 let own = &mut owner;
957 let cell1 = series(4, false, own);
958 let cell2 = series(7, true, own);
959 let cell3 = series(3, true, own);
960 assert_eq!(cell1.ro(own).value(), 4);
961 cell1.rw(own).step();
962 assert_eq!(cell1.ro(own).value(), 5);
963 assert_eq!(own.ro(&cell2).value(), 49);
964 own.rw(&cell2).step();
965 assert_eq!(own.ro(&cell2).value(), 64);
966 let (r1, r2, r3) = own.rw3(&cell1, &cell2, &cell3);
967 r1.step();
968 r2.step();
969 r3.step();
970 assert_eq!(cell1.ro(own).value(), 6);
971 assert_eq!(cell2.ro(own).value(), 81);
972 assert_eq!(cell3.ro(own).value(), 16);
973 let (r1, r2) = own.rw2(&cell1, &cell2);
974 r1.step();
975 r2.step();
976 assert_eq!(cell1.ro(own).value(), 7);
977 assert_eq!(cell2.ro(own).value(), 100);
978 }
979}