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