1#![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 super::{
26 executor::Executor,
27 stateless::{StatelessServiceFactory, StatelessServiceInstance},
28};
29
30#[implement(IFabricStatelessServiceFactory)]
31pub struct StatelessServiceFactoryBridge<E, F>
32where
33 E: Executor + 'static,
34 F: StatelessServiceFactory + 'static,
35{
36 inner: F,
37 rt: E,
38}
39
40impl<E, F> StatelessServiceFactoryBridge<E, F>
41where
42 E: Executor,
43 F: StatelessServiceFactory,
44{
45 pub fn create(factory: F, rt: E) -> StatelessServiceFactoryBridge<E, F> {
46 StatelessServiceFactoryBridge::<E, F> { inner: factory, rt }
47 }
48}
49
50impl<E, F> IFabricStatelessServiceFactory_Impl for StatelessServiceFactoryBridge_Impl<E, F>
51where
52 E: Executor,
53 F: StatelessServiceFactory,
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
96struct IFabricStatelessServiceInstanceBridge<E, S>
97where
98 E: Executor,
99 S: StatelessServiceInstance + 'static,
100{
101 inner: Arc<S>,
102 rt: E,
103}
104
105impl<E, S> IFabricStatelessServiceInstanceBridge<E, S>
106where
107 E: Executor,
108 S: StatelessServiceInstance,
109{
110 pub fn create(instance: S, rt: E) -> IFabricStatelessServiceInstanceBridge<E, S>
111 where
112 S: StatelessServiceInstance,
113 {
114 IFabricStatelessServiceInstanceBridge {
115 inner: Arc::new(instance),
116 rt,
117 }
118 }
119}
120
121impl<E, S> IFabricStatelessServiceInstance_Impl for IFabricStatelessServiceInstanceBridge_Impl<E, S>
122where
123 E: Executor,
124 S: StatelessServiceInstance + 'static,
125{
126 #[cfg_attr(
127 feature = "tracing",
128 tracing::instrument(skip_all, ret(level = "debug"), err)
129 )]
130 fn BeginOpen(
131 &self,
132 partition: windows_core::Ref<IFabricStatelessServicePartition>,
133 callback: windows_core::Ref<super::IFabricAsyncOperationCallback>,
134 ) -> crate::WinResult<super::IFabricAsyncOperationContext> {
135 let partition_cp = partition.unwrap().clone();
136 let partition_bridge = StatelessServicePartition::new(partition_cp);
137 let inner = self.inner.clone();
138 let (ctx, token) = BridgeContext::make(callback);
139 ctx.spawn(&self.rt, async move {
140 inner
141 .open(partition_bridge, token)
142 .await
143 .map(|s| IFabricStringResult::from(StringResult::new(s)))
144 .map_err(crate::WinError::from)
145 })
146 }
147
148 #[cfg_attr(
149 feature = "tracing",
150 tracing::instrument(skip_all, ret(level = "debug"), err)
151 )]
152 fn EndOpen(
153 &self,
154 context: windows_core::Ref<super::IFabricAsyncOperationContext>,
155 ) -> crate::WinResult<IFabricStringResult> {
156 BridgeContext::result(context)?
157 }
158
159 #[cfg_attr(
160 feature = "tracing",
161 tracing::instrument(skip_all, ret(level = "debug"), err)
162 )]
163 fn BeginClose(
164 &self,
165 callback: windows_core::Ref<super::IFabricAsyncOperationCallback>,
166 ) -> crate::WinResult<super::IFabricAsyncOperationContext> {
167 let inner = self.inner.clone();
168 let (ctx, token) = BridgeContext::make(callback);
169 ctx.spawn(&self.rt, async move {
170 inner.close(token).await.map_err(crate::WinError::from)
171 })
172 }
173
174 #[cfg_attr(
175 feature = "tracing",
176 tracing::instrument(skip_all, ret(level = "debug"), err)
177 )]
178 fn EndClose(
179 &self,
180 context: windows_core::Ref<super::IFabricAsyncOperationContext>,
181 ) -> crate::WinResult<()> {
182 BridgeContext::result(context)?
183 }
184
185 #[cfg_attr(
186 feature = "tracing",
187 tracing::instrument(skip_all, ret(level = "debug"))
188 )]
189 fn Abort(&self) {
190 self.inner.abort()
191 }
192}