Skip to content

Commit ac72879

Browse files
DarksonnGerrit Code Review
authored andcommitted
Merge "rust: properly handle async->async handles" into main
2 parents 6a16967 + 0ae829e commit ac72879

2 files changed

Lines changed: 49 additions & 10 deletions

File tree

libs/binder/rust/src/binder.rs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -768,14 +768,14 @@ macro_rules! declare_binder_interface {
768768
$interface:path[$descriptor:expr] {
769769
native: $native:ident($on_transact:path),
770770
proxy: $proxy:ident,
771-
$(async: $async_interface:ident,)?
771+
$(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
772772
}
773773
} => {
774774
$crate::declare_binder_interface! {
775775
$interface[$descriptor] {
776776
native: $native($on_transact),
777777
proxy: $proxy {},
778-
$(async: $async_interface,)?
778+
$(async: $async_interface $(($try_into_local_async))?,)?
779779
stability: $crate::binder_impl::Stability::default(),
780780
}
781781
}
@@ -785,15 +785,15 @@ macro_rules! declare_binder_interface {
785785
$interface:path[$descriptor:expr] {
786786
native: $native:ident($on_transact:path),
787787
proxy: $proxy:ident,
788-
$(async: $async_interface:ident,)?
788+
$(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
789789
stability: $stability:expr,
790790
}
791791
} => {
792792
$crate::declare_binder_interface! {
793793
$interface[$descriptor] {
794794
native: $native($on_transact),
795795
proxy: $proxy {},
796-
$(async: $async_interface,)?
796+
$(async: $async_interface $(($try_into_local_async))?,)?
797797
stability: $stability,
798798
}
799799
}
@@ -805,7 +805,7 @@ macro_rules! declare_binder_interface {
805805
proxy: $proxy:ident {
806806
$($fname:ident: $fty:ty = $finit:expr),*
807807
},
808-
$(async: $async_interface:ident,)?
808+
$(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
809809
}
810810
} => {
811811
$crate::declare_binder_interface! {
@@ -814,7 +814,7 @@ macro_rules! declare_binder_interface {
814814
proxy: $proxy {
815815
$($fname: $fty = $finit),*
816816
},
817-
$(async: $async_interface,)?
817+
$(async: $async_interface $(($try_into_local_async))?,)?
818818
stability: $crate::binder_impl::Stability::default(),
819819
}
820820
}
@@ -826,7 +826,7 @@ macro_rules! declare_binder_interface {
826826
proxy: $proxy:ident {
827827
$($fname:ident: $fty:ty = $finit:expr),*
828828
},
829-
$(async: $async_interface:ident,)?
829+
$(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
830830
stability: $stability:expr,
831831
}
832832
} => {
@@ -838,7 +838,7 @@ macro_rules! declare_binder_interface {
838838
proxy: $proxy {
839839
$($fname: $fty = $finit),*
840840
},
841-
$(async: $async_interface,)?
841+
$(async: $async_interface $(($try_into_local_async))?,)?
842842
stability: $stability,
843843
}
844844
}
@@ -854,7 +854,7 @@ macro_rules! declare_binder_interface {
854854
$($fname:ident: $fty:ty = $finit:expr),*
855855
},
856856

857-
$( async: $async_interface:ident, )?
857+
$(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
858858

859859
stability: $stability:expr,
860860
}
@@ -1043,6 +1043,24 @@ macro_rules! declare_binder_interface {
10431043
}
10441044

10451045
if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
1046+
let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
1047+
std::convert::TryFrom::try_from(ibinder.clone());
1048+
$(
1049+
// This part is only generated if the user of the macro specifies that the
1050+
// trait has an `try_into_local_async` implementation.
1051+
if let Ok(service) = service {
1052+
if let Some(async_service) = $native::$try_into_local_async(service) {
1053+
// We were able to associate with our expected class,
1054+
// the service is local, and the local service is async.
1055+
return Ok(async_service);
1056+
}
1057+
// The service is local but not async. Fall back to treating it as a
1058+
// remote service. This means that calls to this local service have an
1059+
// extra performance cost due to serialization, but async handle to
1060+
// non-async server is considered a rare case, so this is okay.
1061+
}
1062+
)?
1063+
// Treat service as remote.
10461064
return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
10471065
}
10481066

libs/binder/rust/tests/integration.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ declare_binder_interface! {
182182
proxy: BpTest {
183183
x: i32 = 100
184184
},
185-
async: IATest,
185+
async: IATest(try_into_local_async),
186186
}
187187
}
188188

@@ -323,6 +323,14 @@ impl<P: binder::BinderAsyncPool> IATest<P> for Binder<BnTest> {
323323
}
324324
}
325325

326+
impl BnTest {
327+
fn try_into_local_async<P: binder::BinderAsyncPool + 'static>(
328+
me: Binder<BnTest>,
329+
) -> Option<binder::Strong<dyn IATest<P>>> {
330+
Some(binder::Strong::new(Box::new(me) as _))
331+
}
332+
}
333+
326334
/// Trivial testing binder interface
327335
pub trait ITestSameDescriptor: Interface {}
328336

@@ -900,6 +908,19 @@ mod tests {
900908
assert_eq!(service.test().unwrap(), service_name);
901909
}
902910

911+
#[tokio::test]
912+
async fn reassociate_rust_binder_async() {
913+
let service_name = "testing_service";
914+
let service_ibinder =
915+
BnTest::new_binder(TestService::new(service_name), BinderFeatures::default())
916+
.as_binder();
917+
918+
let service: Strong<dyn IATest<Tokio>> =
919+
service_ibinder.into_interface().expect("Could not reassociate the generic ibinder");
920+
921+
assert_eq!(service.test().await.unwrap(), service_name);
922+
}
923+
903924
#[test]
904925
fn weak_binder_upgrade() {
905926
let service_name = "testing_service";

0 commit comments

Comments
 (0)