@@ -6,12 +6,13 @@ use crate::ffi::c_void;
66use core:: {
77 cell:: UnsafeCell ,
88 marker:: { PhantomData , PhantomPinned } ,
9- mem:: { ManuallyDrop , MaybeUninit } ,
9+ mem:: MaybeUninit ,
1010 ops:: { Deref , DerefMut } ,
11- ptr:: NonNull ,
1211} ;
1312use pin_init:: { PinInit , Zeroable } ;
1413
14+ pub use crate :: sync:: aref:: { ARef , AlwaysRefCounted } ;
15+
1516/// Used to transfer ownership to and from foreign (non-Rust) languages.
1617///
1718/// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and
@@ -420,155 +421,6 @@ impl<T> Opaque<T> {
420421 }
421422}
422423
423- /// Types that are _always_ reference counted.
424- ///
425- /// It allows such types to define their own custom ref increment and decrement functions.
426- /// Additionally, it allows users to convert from a shared reference `&T` to an owned reference
427- /// [`ARef<T>`].
428- ///
429- /// This is usually implemented by wrappers to existing structures on the C side of the code. For
430- /// Rust code, the recommendation is to use [`Arc`](crate::sync::Arc) to create reference-counted
431- /// instances of a type.
432- ///
433- /// # Safety
434- ///
435- /// Implementers must ensure that increments to the reference count keep the object alive in memory
436- /// at least until matching decrements are performed.
437- ///
438- /// Implementers must also ensure that all instances are reference-counted. (Otherwise they
439- /// won't be able to honour the requirement that [`AlwaysRefCounted::inc_ref`] keep the object
440- /// alive.)
441- pub unsafe trait AlwaysRefCounted {
442- /// Increments the reference count on the object.
443- fn inc_ref ( & self ) ;
444-
445- /// Decrements the reference count on the object.
446- ///
447- /// Frees the object when the count reaches zero.
448- ///
449- /// # Safety
450- ///
451- /// Callers must ensure that there was a previous matching increment to the reference count,
452- /// and that the object is no longer used after its reference count is decremented (as it may
453- /// result in the object being freed), unless the caller owns another increment on the refcount
454- /// (e.g., it calls [`AlwaysRefCounted::inc_ref`] twice, then calls
455- /// [`AlwaysRefCounted::dec_ref`] once).
456- unsafe fn dec_ref ( obj : NonNull < Self > ) ;
457- }
458-
459- /// An owned reference to an always-reference-counted object.
460- ///
461- /// The object's reference count is automatically decremented when an instance of [`ARef`] is
462- /// dropped. It is also automatically incremented when a new instance is created via
463- /// [`ARef::clone`].
464- ///
465- /// # Invariants
466- ///
467- /// The pointer stored in `ptr` is non-null and valid for the lifetime of the [`ARef`] instance. In
468- /// particular, the [`ARef`] instance owns an increment on the underlying object's reference count.
469- pub struct ARef < T : AlwaysRefCounted > {
470- ptr : NonNull < T > ,
471- _p : PhantomData < T > ,
472- }
473-
474- // SAFETY: It is safe to send `ARef<T>` to another thread when the underlying `T` is `Sync` because
475- // it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs
476- // `T` to be `Send` because any thread that has an `ARef<T>` may ultimately access `T` using a
477- // mutable reference, for example, when the reference count reaches zero and `T` is dropped.
478- unsafe impl < T : AlwaysRefCounted + Sync + Send > Send for ARef < T > { }
479-
480- // SAFETY: It is safe to send `&ARef<T>` to another thread when the underlying `T` is `Sync`
481- // because it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally,
482- // it needs `T` to be `Send` because any thread that has a `&ARef<T>` may clone it and get an
483- // `ARef<T>` on that thread, so the thread may ultimately access `T` using a mutable reference, for
484- // example, when the reference count reaches zero and `T` is dropped.
485- unsafe impl < T : AlwaysRefCounted + Sync + Send > Sync for ARef < T > { }
486-
487- impl < T : AlwaysRefCounted > ARef < T > {
488- /// Creates a new instance of [`ARef`].
489- ///
490- /// It takes over an increment of the reference count on the underlying object.
491- ///
492- /// # Safety
493- ///
494- /// Callers must ensure that the reference count was incremented at least once, and that they
495- /// are properly relinquishing one increment. That is, if there is only one increment, callers
496- /// must not use the underlying object anymore -- it is only safe to do so via the newly
497- /// created [`ARef`].
498- pub unsafe fn from_raw ( ptr : NonNull < T > ) -> Self {
499- // INVARIANT: The safety requirements guarantee that the new instance now owns the
500- // increment on the refcount.
501- Self {
502- ptr,
503- _p : PhantomData ,
504- }
505- }
506-
507- /// Consumes the `ARef`, returning a raw pointer.
508- ///
509- /// This function does not change the refcount. After calling this function, the caller is
510- /// responsible for the refcount previously managed by the `ARef`.
511- ///
512- /// # Examples
513- ///
514- /// ```
515- /// use core::ptr::NonNull;
516- /// use kernel::types::{ARef, AlwaysRefCounted};
517- ///
518- /// struct Empty {}
519- ///
520- /// # // SAFETY: TODO.
521- /// unsafe impl AlwaysRefCounted for Empty {
522- /// fn inc_ref(&self) {}
523- /// unsafe fn dec_ref(_obj: NonNull<Self>) {}
524- /// }
525- ///
526- /// let mut data = Empty {};
527- /// let ptr = NonNull::<Empty>::new(&mut data).unwrap();
528- /// # // SAFETY: TODO.
529- /// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
530- /// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
531- ///
532- /// assert_eq!(ptr, raw_ptr);
533- /// ```
534- pub fn into_raw ( me : Self ) -> NonNull < T > {
535- ManuallyDrop :: new ( me) . ptr
536- }
537- }
538-
539- impl < T : AlwaysRefCounted > Clone for ARef < T > {
540- fn clone ( & self ) -> Self {
541- self . inc_ref ( ) ;
542- // SAFETY: We just incremented the refcount above.
543- unsafe { Self :: from_raw ( self . ptr ) }
544- }
545- }
546-
547- impl < T : AlwaysRefCounted > Deref for ARef < T > {
548- type Target = T ;
549-
550- fn deref ( & self ) -> & Self :: Target {
551- // SAFETY: The type invariants guarantee that the object is valid.
552- unsafe { self . ptr . as_ref ( ) }
553- }
554- }
555-
556- impl < T : AlwaysRefCounted > From < & T > for ARef < T > {
557- fn from ( b : & T ) -> Self {
558- b. inc_ref ( ) ;
559- // SAFETY: We just incremented the refcount above.
560- unsafe { Self :: from_raw ( NonNull :: from ( b) ) }
561- }
562- }
563-
564- impl < T : AlwaysRefCounted > Drop for ARef < T > {
565- fn drop ( & mut self ) {
566- // SAFETY: The type invariants guarantee that the `ARef` owns the reference we're about to
567- // decrement.
568- unsafe { T :: dec_ref ( self . ptr ) } ;
569- }
570- }
571-
572424/// Zero-sized type to mark types not [`Send`].
573425///
574426/// Add this type as a field to your struct if your type should not be sent to a different task.
0 commit comments