Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f03fe3d2 authored by Stephen Crane's avatar Stephen Crane
Browse files

[binder_rs] Make Binder interfaces and Strong<> Sync

NDK Binder objects are thread-safe, so our Rust interfaces and Strong<>
objects can be marked as Sync.

Test: atest -p frameworks/native/libs/binder --include-subdirs
Bug: 164453341
Change-Id: I9aea4413cae14af136e1d6f5f4143cce30d65a37
parent 53873097
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ pub type TransactionFlags = u32;
/// interfaces) must implement this trait.
///
/// This is equivalent `IInterface` in C++.
pub trait Interface: Send {
pub trait Interface: Send + Sync {
    /// Convert this binder object into a generic [`SpIBinder`] reference.
    fn as_binder(&self) -> SpIBinder {
        panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
+19 −0
Original line number Diff line number Diff line
@@ -51,6 +51,25 @@ pub struct Binder<T: Remotable> {
/// to how `Box<T>` is `Send` if `T` is `Send`.
unsafe impl<T: Remotable> Send for Binder<T> {}

/// # Safety
///
/// A `Binder<T>` is a pair of unique owning pointers to two values:
///   * a C++ ABBinder which is thread-safe, i.e. `Send + Sync`
///   * a Rust object which implements `Remotable`; this trait requires `Send + Sync`
///
/// `ABBinder` contains an immutable `mUserData` pointer, which is actually a
/// pointer to a boxed `T: Remotable`, which is `Sync`. `ABBinder` also contains
/// a mutable pointer to its class, but mutation of this field is controlled by
/// a mutex and it is only allowed to be set once, therefore we can concurrently
/// access this field safely. `ABBinder` inherits from `BBinder`, which is also
/// thread-safe. Thus `ABBinder` is thread-safe.
///
/// Both pointers are unique (never escape the `Binder<T>` object and are not copied)
/// so we can essentially treat `Binder<T>` as a box-like containing the two objects;
/// the box-like object inherits `Sync` from the two inner values, similarly
/// to how `Box<T>` is `Sync` if `T` is `Sync`.
unsafe impl<T: Remotable> Sync for Binder<T> {}

impl<T: Remotable> Binder<T> {
    /// Create a new Binder remotable object with default stability
    ///
+12 −2
Original line number Diff line number Diff line
@@ -48,9 +48,14 @@ impl fmt::Debug for SpIBinder {

/// # Safety
///
/// An `SpIBinder` is a handle to a C++ IBinder, which is thread-safe
/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
unsafe impl Send for SpIBinder {}

/// # Safety
///
/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
unsafe impl Sync for SpIBinder {}

impl SpIBinder {
    /// Create an `SpIBinder` wrapper object from a raw `AIBinder` pointer.
    ///
@@ -448,9 +453,14 @@ impl fmt::Debug for WpIBinder {

/// # Safety
///
/// A `WpIBinder` is a handle to a C++ IBinder, which is thread-safe.
/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
unsafe impl Send for WpIBinder {}

/// # Safety
///
/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
unsafe impl Sync for WpIBinder {}

impl WpIBinder {
    /// Create a new weak reference from an object that can be converted into a
    /// raw `AIBinder` pointer.