iceoryx2_ffi/api/
port_factory_notifier_builder.rs1#![allow(non_camel_case_types)]
14
15use crate::api::{
16 iox2_event_id_t, iox2_notifier_h, iox2_notifier_t, iox2_service_type_e, AssertNonNullHandle,
17 HandleToType, IntoCInt, NotifierUnion, IOX2_OK,
18};
19
20use iceoryx2::port::notifier::NotifierCreateError;
21use iceoryx2::prelude::*;
22use iceoryx2::service::port_factory::notifier::PortFactoryNotifier;
23use iceoryx2_bb_elementary::static_assert::*;
24use iceoryx2_ffi_macros::iceoryx2_ffi;
25
26use core::ffi::c_int;
27use core::mem::ManuallyDrop;
28
29#[repr(C)]
32#[derive(Copy, Clone)]
33pub enum iox2_notifier_create_error_e {
34 EXCEEDS_MAX_SUPPORTED_NOTIFIERS = IOX2_OK as isize + 1,
35}
36
37impl IntoCInt for NotifierCreateError {
38 fn into_c_int(self) -> c_int {
39 (match self {
40 NotifierCreateError::ExceedsMaxSupportedNotifiers => {
41 iox2_notifier_create_error_e::EXCEEDS_MAX_SUPPORTED_NOTIFIERS
42 }
43 }) as c_int
44 }
45}
46
47pub(super) union PortFactoryNotifierBuilderUnion {
48 ipc: ManuallyDrop<PortFactoryNotifier<'static, ipc::Service>>,
49 local: ManuallyDrop<PortFactoryNotifier<'static, local::Service>>,
50}
51
52impl PortFactoryNotifierBuilderUnion {
53 pub(super) fn new_ipc(port_factory: PortFactoryNotifier<'static, ipc::Service>) -> Self {
54 Self {
55 ipc: ManuallyDrop::new(port_factory),
56 }
57 }
58 pub(super) fn new_local(port_factory: PortFactoryNotifier<'static, local::Service>) -> Self {
59 Self {
60 local: ManuallyDrop::new(port_factory),
61 }
62 }
63}
64
65#[repr(C)]
66#[repr(align(8))] pub struct iox2_port_factory_notifier_builder_storage_t {
68 internal: [u8; 24], }
70
71#[repr(C)]
72#[iceoryx2_ffi(PortFactoryNotifierBuilderUnion)]
73pub struct iox2_port_factory_notifier_builder_t {
74 service_type: iox2_service_type_e,
75 value: iox2_port_factory_notifier_builder_storage_t,
76 deleter: fn(*mut iox2_port_factory_notifier_builder_t),
77}
78
79impl iox2_port_factory_notifier_builder_t {
80 pub(super) fn init(
81 &mut self,
82 service_type: iox2_service_type_e,
83 value: PortFactoryNotifierBuilderUnion,
84 deleter: fn(*mut iox2_port_factory_notifier_builder_t),
85 ) {
86 self.service_type = service_type;
87 self.value.init(value);
88 self.deleter = deleter;
89 }
90}
91
92pub struct iox2_port_factory_notifier_builder_h_t;
93pub type iox2_port_factory_notifier_builder_h = *mut iox2_port_factory_notifier_builder_h_t;
95pub type iox2_port_factory_notifier_builder_h_ref = *const iox2_port_factory_notifier_builder_h;
97
98impl AssertNonNullHandle for iox2_port_factory_notifier_builder_h {
99 fn assert_non_null(self) {
100 debug_assert!(!self.is_null());
101 }
102}
103
104impl AssertNonNullHandle for iox2_port_factory_notifier_builder_h_ref {
105 fn assert_non_null(self) {
106 debug_assert!(!self.is_null());
107 unsafe {
108 debug_assert!(!(*self).is_null());
109 }
110 }
111}
112
113impl HandleToType for iox2_port_factory_notifier_builder_h {
114 type Target = *mut iox2_port_factory_notifier_builder_t;
115
116 fn as_type(self) -> Self::Target {
117 self as *mut _ as _
118 }
119}
120
121impl HandleToType for iox2_port_factory_notifier_builder_h_ref {
122 type Target = *mut iox2_port_factory_notifier_builder_t;
123
124 fn as_type(self) -> Self::Target {
125 unsafe { *self as *mut _ as _ }
126 }
127}
128
129#[no_mangle]
146pub unsafe extern "C" fn iox2_port_factory_notifier_builder_set_default_event_id(
147 port_factory_handle: iox2_port_factory_notifier_builder_h_ref,
148 value: *const iox2_event_id_t,
149) {
150 port_factory_handle.assert_non_null();
151
152 let value = (*value).into();
153
154 let port_factory_struct = unsafe { &mut *port_factory_handle.as_type() };
155 match port_factory_struct.service_type {
156 iox2_service_type_e::IPC => {
157 let port_factory = ManuallyDrop::take(&mut port_factory_struct.value.as_mut().ipc);
158
159 port_factory_struct.set(PortFactoryNotifierBuilderUnion::new_ipc(
160 port_factory.default_event_id(value),
161 ));
162 }
163 iox2_service_type_e::LOCAL => {
164 let port_factory = ManuallyDrop::take(&mut port_factory_struct.value.as_mut().local);
165
166 port_factory_struct.set(PortFactoryNotifierBuilderUnion::new_local(
167 port_factory.default_event_id(value),
168 ));
169 }
170 }
171}
172
173#[no_mangle]
189pub unsafe extern "C" fn iox2_port_factory_notifier_builder_create(
190 port_factory_handle: iox2_port_factory_notifier_builder_h,
191 notifier_struct_ptr: *mut iox2_notifier_t,
192 notifier_handle_ptr: *mut iox2_notifier_h,
193) -> c_int {
194 debug_assert!(!port_factory_handle.is_null());
195 debug_assert!(!notifier_handle_ptr.is_null());
196
197 let mut notifier_struct_ptr = notifier_struct_ptr;
198 fn no_op(_: *mut iox2_notifier_t) {}
199 let mut deleter: fn(*mut iox2_notifier_t) = no_op;
200 if notifier_struct_ptr.is_null() {
201 notifier_struct_ptr = iox2_notifier_t::alloc();
202 deleter = iox2_notifier_t::dealloc;
203 }
204 debug_assert!(!notifier_struct_ptr.is_null());
205
206 let notifier_builder_struct = unsafe { &mut *port_factory_handle.as_type() };
207 let service_type = notifier_builder_struct.service_type;
208 let notifier_builder = notifier_builder_struct
209 .value
210 .as_option_mut()
211 .take()
212 .unwrap_or_else(|| {
213 panic!("Trying to use an invalid 'iox2_port_factory_notifier_builder_h'!")
214 });
215 (notifier_builder_struct.deleter)(notifier_builder_struct);
216
217 match service_type {
218 iox2_service_type_e::IPC => {
219 let notifier_builder = ManuallyDrop::into_inner(notifier_builder.ipc);
220
221 match notifier_builder.create() {
222 Ok(notifier) => {
223 (*notifier_struct_ptr).init(
224 service_type,
225 NotifierUnion::new_ipc(notifier),
226 deleter,
227 );
228 }
229 Err(error) => {
230 return error.into_c_int();
231 }
232 }
233 }
234 iox2_service_type_e::LOCAL => {
235 let notifier_builder = ManuallyDrop::into_inner(notifier_builder.local);
236
237 match notifier_builder.create() {
238 Ok(notifier) => {
239 (*notifier_struct_ptr).init(
240 service_type,
241 NotifierUnion::new_local(notifier),
242 deleter,
243 );
244 }
245 Err(error) => {
246 return error.into_c_int();
247 }
248 }
249 }
250 }
251
252 *notifier_handle_ptr = (*notifier_struct_ptr).as_handle();
253
254 IOX2_OK
255}
256
257