Skip to main content

lmflow/ffi/
kernel_runner.rs

1use super::*;
2
3unsafe fn runner_ref<'a>(p: *mut LMFlowKernelRunner) -> Option<&'a mut KernelRunnerHandle> {
4    (!p.is_null()).then(|| &mut *(p as *mut KernelRunnerHandle))
5}
6
7#[no_mangle]
8pub unsafe extern "C" fn lmflow_kernel_runner_new(
9    kernel: *const c_char,
10    input_ports: usize,
11    output_ports: usize,
12) -> *mut LMFlowKernelRunner {
13    guard_val(std::ptr::null_mut(), || {
14        let Some(name) = cstr(kernel) else {
15            last_error::set("kernel name is null");
16            return std::ptr::null_mut();
17        };
18        match KernelRunner::new(name, input_ports, output_ports) {
19            Ok(runner) => {
20                Box::into_raw(Box::new(KernelRunnerHandle { runner })) as *mut LMFlowKernelRunner
21            }
22            Err(error) => {
23                last_error::set(&error.to_string());
24                std::ptr::null_mut()
25            }
26        }
27    })
28}
29
30#[no_mangle]
31pub unsafe extern "C" fn lmflow_kernel_runner_free(p: *mut LMFlowKernelRunner) {
32    guard_val((), || {
33        if !p.is_null() {
34            drop(Box::from_raw(p as *mut KernelRunnerHandle));
35        }
36    });
37}
38
39#[no_mangle]
40pub unsafe extern "C" fn lmflow_kernel_runner_start(p: *mut LMFlowKernelRunner) -> i32 {
41    guard(|| {
42        let Some(handle) = runner_ref(p) else {
43            return fail(Error::InvalidArg("kernel runner handle is null".into()));
44        };
45        to_status(handle.runner.open())
46    })
47}
48
49#[no_mangle]
50pub unsafe extern "C" fn lmflow_kernel_runner_set_options_json(
51    p: *mut LMFlowKernelRunner,
52    json: *const c_char,
53) -> i32 {
54    guard(|| {
55        let Some(handle) = runner_ref(p) else {
56            return fail(Error::InvalidArg("kernel runner handle is null".into()));
57        };
58        let Some(json) = cstr(json) else {
59            return fail(Error::InvalidArg(
60                "options JSON is null or invalid UTF-8".into(),
61            ));
62        };
63        to_status(handle.runner.set_options_json(json))
64    })
65}
66
67#[no_mangle]
68pub unsafe extern "C" fn lmflow_kernel_runner_set_side_packet(
69    p: *mut LMFlowKernelRunner,
70    name: *const c_char,
71    packet: LMFlowPacket,
72) -> i32 {
73    guard(|| {
74        let owned = take_packet(packet);
75        let Some(handle) = runner_ref(p) else {
76            return fail(Error::InvalidArg("kernel runner handle is null".into()));
77        };
78        let Some(name) = cstr(name) else {
79            return fail(Error::InvalidArg("side packet name is null".into()));
80        };
81        to_status(handle.runner.set_side_packet(name, owned))
82    })
83}
84
85#[no_mangle]
86pub unsafe extern "C" fn lmflow_kernel_runner_add_input(
87    p: *mut LMFlowKernelRunner,
88    port: usize,
89    packet: LMFlowPacket,
90) -> i32 {
91    guard(|| {
92        let owned = take_packet(packet);
93        let Some(handle) = runner_ref(p) else {
94            return fail(Error::InvalidArg("kernel runner handle is null".into()));
95        };
96        to_status(handle.runner.add_input(port, owned))
97    })
98}
99
100#[no_mangle]
101pub unsafe extern "C" fn lmflow_kernel_runner_process(
102    p: *mut LMFlowKernelRunner,
103    timestamp: i64,
104) -> i32 {
105    guard(|| {
106        let Some(handle) = runner_ref(p) else {
107            return fail(Error::InvalidArg("kernel runner handle is null".into()));
108        };
109        match handle
110            .runner
111            .process_pending(crate::timestamp::Timestamp(timestamp))
112        {
113            Ok(_) => code::OK,
114            Err(error) => fail(error),
115        }
116    })
117}
118
119#[no_mangle]
120pub unsafe extern "C" fn lmflow_kernel_runner_try_next(
121    p: *mut LMFlowKernelRunner,
122    port: usize,
123    out: *mut LMFlowPacket,
124) -> i32 {
125    guard(|| {
126        let Some(handle) = runner_ref(p) else {
127            return fail(Error::InvalidArg("kernel runner handle is null".into()));
128        };
129        match handle.runner.try_output(port) {
130            Ok(Some(packet)) => {
131                if !out.is_null() {
132                    *out = own_packet(packet);
133                }
134                code::OK
135            }
136            Ok(None) => code::WOULD_BLOCK,
137            Err(error) => fail(error),
138        }
139    })
140}
141
142#[no_mangle]
143pub unsafe extern "C" fn lmflow_kernel_runner_close(p: *mut LMFlowKernelRunner) -> i32 {
144    guard(|| {
145        let Some(handle) = runner_ref(p) else {
146            return fail(Error::InvalidArg("kernel runner handle is null".into()));
147        };
148        match handle.runner.close() {
149            Ok(_) => code::OK,
150            Err(error) => fail(error),
151        }
152    })
153}