• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }