Loading libs/binder/rust/binder_tokio/lib.rs +32 −13 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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) Loading Loading @@ -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 Loading @@ -99,5 +119,4 @@ impl BinderAsyncPool for Tokio { }) } } } libs/binder/rust/src/lib.rs +1 −1 Original line number Diff line number Diff line Loading @@ -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}; Loading libs/binder/rust/src/native.rs +9 −0 Original line number Diff line number Diff line Loading @@ -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() } } Loading
libs/binder/rust/binder_tokio/lib.rs +32 −13 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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) Loading Loading @@ -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 Loading @@ -99,5 +119,4 @@ impl BinderAsyncPool for Tokio { }) } } }
libs/binder/rust/src/lib.rs +1 −1 Original line number Diff line number Diff line Loading @@ -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}; Loading
libs/binder/rust/src/native.rs +9 −0 Original line number Diff line number Diff line Loading @@ -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() } }