mssf_core/runtime/
stateless_bridge.rs1#![allow(non_camel_case_types)]
8
9use std::sync::Arc;
10
11use crate::{
12 runtime::StatelessServicePartition, strings::StringResult, sync::BridgeContext, types::Uri,
13};
14use mssf_com::{
15 FabricCommon::IFabricStringResult,
16 FabricRuntime::{
17 IFabricStatelessServiceFactory, IFabricStatelessServiceFactory_Impl,
18 IFabricStatelessServiceInstance, IFabricStatelessServiceInstance_Impl,
19 IFabricStatelessServicePartition,
20 },
21 FabricTypes::FABRIC_URI,
22};
23use windows_core::{WString, implement};
24
25use crate::runtime::{
26 executor::Executor,
27 {IStatelessServiceFactory, IStatelessServiceInstance},
28};
29
30#[implement(IFabricStatelessServiceFactory)]
31pub struct StatelessServiceFactoryBridge<E>
32where
33 E: Executor + 'static,
34{
35 inner: Box<dyn IStatelessServiceFactory>,
36 rt: E,
37}
38
39impl<E> StatelessServiceFactoryBridge<E>
40where
41 E: Executor,
42{
43 pub fn create(
44 factory: Box<dyn IStatelessServiceFactory>,
45 rt: E,
46 ) -> StatelessServiceFactoryBridge<E> {
47 StatelessServiceFactoryBridge { inner: factory, rt }
48 }
49}
50
51impl<E> IFabricStatelessServiceFactory_Impl for StatelessServiceFactoryBridge_Impl<E>
52where
53 E: Executor,
54{
55 #[allow(clippy::not_unsafe_ptr_arg_deref)]
56 #[cfg_attr(
57 feature = "tracing",
58 tracing::instrument(skip_all, ret(level = "debug"), err)
59 )]
60 fn CreateInstance(
61 &self,
62 servicetypename: &crate::PCWSTR,
63 servicename: FABRIC_URI,
64 initializationdatalength: u32,
65 initializationdata: *const u8,
66 partitionid: &crate::GUID,
67 instanceid: i64,
68 ) -> crate::WinResult<IFabricStatelessServiceInstance> {
69 let h_servicename = Uri::from(servicename);
70 let h_servicetypename = WString::from(*servicetypename);
71 let data = unsafe {
72 if !initializationdata.is_null() {
73 std::slice::from_raw_parts(initializationdata, initializationdatalength as usize)
74 } else {
75 &[]
76 }
77 };
78
79 let instance = self.inner.create_instance(
80 h_servicetypename,
81 h_servicename,
82 data,
83 *partitionid,
84 instanceid,
85 )?;
86 let rt = self.rt.clone();
87 let instance_bridge = IFabricStatelessServiceInstanceBridge::create(instance, rt);
88
89 Ok(instance_bridge.into())
90 }
91}
92
93#[implement(IFabricStatelessServiceInstance)]
95
96pub(crate) struct IFabricStatelessServiceInstanceBridge<E>
97where
98 E: Executor,
99{
100 inner: Arc<Box<dyn IStatelessServiceInstance>>,
101 rt: E,
102}
103
104impl<E> IFabricStatelessServiceInstanceBridge<E>
105where
106 E: Executor,
107{
108 pub fn create(
109 instance: Box<dyn IStatelessServiceInstance>,
110 rt: E,
111 ) -> IFabricStatelessServiceInstanceBridge<E> {
112 IFabricStatelessServiceInstanceBridge {
113 inner: Arc::new(instance),
114 rt,
115 }
116 }
117}
118
119impl<E> IFabricStatelessServiceInstance_Impl for IFabricStatelessServiceInstanceBridge_Impl<E>
120where
121 E: Executor,
122{
123 #[cfg_attr(
124 feature = "tracing",
125 tracing::instrument(skip_all, ret(level = "debug"), err)
126 )]
127 fn BeginOpen(
128 &self,
129 partition: windows_core::Ref<IFabricStatelessServicePartition>,
130 callback: windows_core::Ref<super::IFabricAsyncOperationCallback>,
131 ) -> crate::WinResult<super::IFabricAsyncOperationContext> {
132 let partition_cp = partition.unwrap().clone();
133 let partition_bridge = StatelessServicePartition::new(partition_cp);
134 let inner = self.inner.clone();
135 let (ctx, token) = BridgeContext::make(callback);
136 ctx.spawn(&self.rt, async move {
137 inner
138 .open(Arc::new(partition_bridge), token)
139 .await
140 .map(|s| IFabricStringResult::from(StringResult::new(s)))
141 .map_err(crate::WinError::from)
142 })
143 }
144
145 #[cfg_attr(
146 feature = "tracing",
147 tracing::instrument(skip_all, ret(level = "debug"), err)
148 )]
149 fn EndOpen(
150 &self,
151 context: windows_core::Ref<super::IFabricAsyncOperationContext>,
152 ) -> crate::WinResult<IFabricStringResult> {
153 BridgeContext::result(context)?
154 }
155
156 #[cfg_attr(
157 feature = "tracing",
158 tracing::instrument(skip_all, ret(level = "debug"), err)
159 )]
160 fn BeginClose(
161 &self,
162 callback: windows_core::Ref<super::IFabricAsyncOperationCallback>,
163 ) -> crate::WinResult<super::IFabricAsyncOperationContext> {
164 let inner = self.inner.clone();
165 let (ctx, token) = BridgeContext::make(callback);
166 ctx.spawn(&self.rt, async move {
167 inner.close(token).await.map_err(crate::WinError::from)
168 })
169 }
170
171 #[cfg_attr(
172 feature = "tracing",
173 tracing::instrument(skip_all, ret(level = "debug"), err)
174 )]
175 fn EndClose(
176 &self,
177 context: windows_core::Ref<super::IFabricAsyncOperationContext>,
178 ) -> crate::WinResult<()> {
179 BridgeContext::result(context)?
180 }
181
182 #[cfg_attr(
183 feature = "tracing",
184 tracing::instrument(skip_all, ret(level = "debug"))
185 )]
186 fn Abort(&self) {
187 self.inner.abort()
188 }
189}