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

Commit 55f395a6 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "binder_tokio: only use threadpool for new transactions"

parents 46acb2b0 ad9c77bb
Loading
Loading
Loading
Loading
+32 −13
Original line number Diff line number Diff line
@@ -35,6 +35,11 @@ use std::future::Future;
/// Retrieve an existing service for a particular interface, sleeping for a few
/// seconds if it doesn't yet exist.
pub async fn get_interface<T: FromIBinder + ?Sized + 'static>(name: &str) -> Result<Strong<T>, StatusCode> {
    if binder::is_handling_transaction() {
        // See comment in the BinderAsyncPool impl.
        return binder::public_api::get_interface::<T>(name);
    }

    let name = name.to_string();
    let res = tokio::task::spawn_blocking(move || {
        binder::public_api::get_interface::<T>(&name)
@@ -54,6 +59,11 @@ pub async fn get_interface<T: FromIBinder + ?Sized + 'static>(name: &str) -> Res
/// Retrieve an existing service for a particular interface, or start it if it
/// is configured as a dynamic service and isn't yet started.
pub async fn wait_for_interface<T: FromIBinder + ?Sized + 'static>(name: &str) -> Result<Strong<T>, StatusCode> {
    if binder::is_handling_transaction() {
        // See comment in the BinderAsyncPool impl.
        return binder::public_api::wait_for_interface::<T>(name);
    }

    let name = name.to_string();
    let res = tokio::task::spawn_blocking(move || {
        binder::public_api::wait_for_interface::<T>(&name)
@@ -86,6 +96,16 @@ impl BinderAsyncPool for Tokio {
        B: Send + 'a,
        E: From<crate::StatusCode>,
    {
        if binder::is_handling_transaction() {
            // We are currently on the thread pool for a binder server, so we should execute the
            // transaction on the current thread so that the binder kernel driver is able to apply
            // its deadlock prevention strategy to the sub-call.
            //
            // This shouldn't cause issues with blocking the thread as only one task will run in a
            // call to `block_on`, so there aren't other tasks to block.
            let result = spawn_me();
            Box::pin(after_spawn(result))
        } else {
            let handle = tokio::task::spawn_blocking(spawn_me);
            Box::pin(async move {
                // The `is_panic` branch is not actually reachable in Android as we compile
@@ -99,5 +119,4 @@ impl BinderAsyncPool for Tokio {
            })
        }
    }

}
+1 −1
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@ pub use crate::binder::{
};
pub use crate::binder_async::{BoxFuture, BinderAsyncPool};
pub use error::{status_t, ExceptionCode, Result, Status, StatusCode};
pub use native::{add_service, force_lazy_services_persist, register_lazy_service, Binder};
pub use native::{add_service, force_lazy_services_persist, is_handling_transaction, register_lazy_service, Binder};
pub use parcel::{BorrowedParcel, Parcel};
pub use proxy::{get_interface, get_service, wait_for_interface, wait_for_service};
pub use proxy::{AssociateClass, DeathRecipient, Proxy, SpIBinder, WpIBinder};
+9 −0
Original line number Diff line number Diff line
@@ -517,3 +517,12 @@ impl Remotable for () {
}

impl Interface for () {}

/// Determine whether the current thread is currently executing an incoming
/// transaction.
pub fn is_handling_transaction() -> bool {
    unsafe {
        // Safety: This method is always safe to call.
        sys::AIBinder_isHandlingTransaction()
    }
}