1 /* 2 * Copyright (C) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 pub mod ipc_ylong; 17 pub use ipc_ylong::{Runtime, Ylong}; 18 19 use crate::errors::{IpcResult}; 20 use crate::ipc::{RemoteObjRef, FromRemoteObj}; 21 use crate::IRemoteBroker; 22 use std::future::Future; 23 use std::pin::Pin; 24 use ylong_runtime::task::JoinHandle; 25 26 /// A type alias for a pinned, boxed future that lets you write shorter code without littering it 27 /// with Pin and Send bounds. 28 pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>; 29 30 /// A thread pool for running ipc transactions. 31 pub trait IpcAsyncPool { 32 /// This function should conceptually behave like this: 33 /// 34 /// ```text 35 /// let result = spawn(spawn, after_handle).await; 36 /// ``` spawn<'a, F1, F2, Fut, A, B>(spawn_this: F1, after_handle: F2) -> BoxFuture<'a, IpcResult<B>> where F1: FnOnce() -> A, F2: FnOnce(A) -> Fut, Fut: Future<Output = IpcResult<B>>, F1: Send + 'static, F2: Send + 'a, Fut: Send + 'a, A: Send + 'static, B: Send + 'a,37 fn spawn<'a, F1, F2, Fut, A, B>(spawn_this: F1, after_handle: F2) -> BoxFuture<'a, IpcResult<B>> 38 where 39 F1: FnOnce() -> A, 40 F2: FnOnce(A) -> Fut, 41 Fut: Future<Output = IpcResult<B>>, 42 F1: Send + 'static, 43 F2: Send + 'a, 44 Fut: Send + 'a, 45 A: Send + 'static, 46 B: Send + 'a,; 47 } 48 49 /// A runtime for executing an async ipc server. 50 pub trait IpcAsyncRuntime { 51 /// Using the default task setting, spawns a task onto the global runtime. spawn<T, R>(task: T) -> JoinHandle<R> where T: Future<Output = R>, T: Send + 'static, R: Send + 'static,52 fn spawn<T, R>(task: T) -> JoinHandle<R> 53 where 54 T: Future<Output = R>, 55 T: Send + 'static, 56 R: Send + 'static,; 57 58 /// Using the default task setting, spawns a blocking task. spawn_blocking<T, R>(task: T) -> JoinHandle<R> where T: FnOnce() -> R, T: Send + 'static, R: Send + 'static,59 fn spawn_blocking<T, R>(task: T) -> JoinHandle<R> 60 where 61 T: FnOnce() -> R, 62 T: Send + 'static, 63 R: Send + 'static,; 64 65 /// Block on the provided future, running it to completion and returning its output. block_on<F: Future>(future: F) -> F::Output66 fn block_on<F: Future>(future: F) -> F::Output; 67 } 68 69 /// Implemented by sync interfaces to specify what the associated async interface is. 70 /// Generic to handle the fact that async interfaces are generic over a thread pool. 71 /// 72 /// The binder in any object implementing this trait should be compatible with the 73 /// `Target` associated type, and using `FromIBinder` to convert it to the target 74 /// should not fail. 75 pub trait ToAsyncIpc<P> 76 where 77 Self: IRemoteBroker, 78 Self::Target: FromRemoteObj, 79 { 80 /// The async interface associated with this sync interface. 81 type Target: ?Sized; 82 } 83 84 /// Implemented by async interfaces to specify what the associated sync interface is. 85 /// 86 /// The binder in any object implementing this trait should be compatible with the 87 /// `Target` associated type, and using `FromRemoteObj` to convert it to the target 88 /// should not fail. 89 pub trait ToSyncIpc 90 where 91 Self: IRemoteBroker, 92 Self::Target: FromRemoteObj, 93 { 94 /// The sync interface associated with this async interface. 95 type Target: ?Sized; 96 } 97 98 impl<I: FromRemoteObj + ?Sized> RemoteObjRef<I> { 99 /// Convert this synchronous remote object handle into an asynchronous one. into_async<P>(&self) -> RemoteObjRef<<I as ToAsyncIpc<P>>::Target> where I: ToAsyncIpc<P>,100 pub fn into_async<P>(&self) -> RemoteObjRef<<I as ToAsyncIpc<P>>::Target> 101 where 102 I: ToAsyncIpc<P>, 103 { 104 // By implementing the ToAsyncIpc trait, it is guaranteed that the remote 105 // object is also valid for the target type. 106 FromRemoteObj::try_from(self.as_object().unwrap()).unwrap() 107 } 108 109 /// Convert this asynchronous remote object handle into a synchronous one. into_sync(&self) -> RemoteObjRef<<I as ToSyncIpc>::Target> where I: ToSyncIpc,110 pub fn into_sync(&self) -> RemoteObjRef<<I as ToSyncIpc>::Target> 111 where 112 I: ToSyncIpc, 113 { 114 // By implementing the ToSyncIpc trait, it is guaranteed that the binder 115 // object is also valid for the target type. 116 FromRemoteObj::try_from(self.as_object().unwrap()).unwrap() 117 } 118 }